基础
-
JAVA是值传递,如果传递参数是基本类型,那么就传递的就是该值的拷贝,如果传递的是引用,那么就传递该引用的对象在heap中地址值的拷贝。(此时该引用与该引用的拷贝指向同一个对象实例,如果在方法中重新实例化对象并指向该引用,那么后续修改的都是新对象地址所对应的对象实例)。
-
JAVA创建对象的方式:1.new对象 2.通过反射 3.序列化 4.重写clone
-
深复制、浅复制:浅复制创建了新的对象,复制了原对象的值(这个值包括基本类型的值和引用的对象地址值),深复制会创建新的对象,对原对象中的非基本类型,新对象中会重新创建对象,再将原来对象的值复制过来(如果对象中包含其它非基本类型,那么该类型也要重写clone方法才可以实现对象的深复制)。
-
String str=”xxx”;,这种字符串常量,在编译期就被确定在常量池(存储在方法区)中,不管有多少引用,指向的地址都是唯一的。String str=new String (xxx);不同,其在编译期无法确定,在运行时会创建一个新对象的引用,地址指向heap中的对象实例,如果调用intern()方法,会尝试将该对象放入常量池中,并返回常量池中的地址。
-
a=a+b和a+=b的区别:a+b会带来类型提升,提升short, byte到int类型,如果a是short,byte类型,会无法通过编译。
-
wait()或notify()/notifyAll()的前提是必须持有当前对象的锁。notify()会把当前对象阻塞的线程随机唤醒。
-
ThreadLocal以空间换时间,在Thread里维护了一个ThreadLocalMap对线程间的数据进行隔离,从另外一个角度上保证了线程安全,key为ThreadLocal对象,value为具体值。
-
volatile可以使变量保持线程间可见性,不能完全保证线程安全(有条件),经volatile修饰的变量在工作内存中发生改变后会强制写回主存,可用于状态控制,写锁场景。
- 工作内存和主存的交互有以下原子操作:load、read、use、assign、store、write、lock、unlock
- 经过volatile修饰过的变量,在assign之前不能被load和read,并且assign后紧跟store和write。
- 具有可见性、但不具备原子性。