1、缓冲池
1) new Integer(123) 每次都创建一个新的对象;
2) Integer.valueOf(123)会使用缓冲池中的对象,多次调用会去掉同一对象引用;先判断是否在缓冲池,如果在的话就直接返回缓冲池的内容。valueOf() 方法用于返回给定参数的原生 Number 对象值,参数可以是原生数据类型, String等。该方法是静态方法。该方法可以接收两个参数一个是字符串,一个是基数。
Integer在java8中大小默认为-128-127;
Integer x = new Integer(123);
Integer y = new Integer(123);
System.out.println(x==y);//false
Integer z= Integer.valueOf(123);
Integer k= Integer.valueOf(123);
System.out.println(z==k);//true
System.out.println("z等于: "+z); //123
Integer xx = 123;
Integer yy = 123;
System.out.println(xx==yy);
3)编译器会在自动装箱过程调用 valueOf() 方法,因此多个值相同且值在缓存池范围内的 Integer 实例使用自动装箱来创建,那么就会引用相同的对象。
4)缓冲池中boolean值为true和false; short是-128-127; int为-128-127; char为\u0000-\u007f; 在使用这些基本类型对应的包装类型时,如果该数值范围在缓冲池范围内,就可以直接使用缓冲池中的对象。
2、String
1) final,不可继承;java8中其内部为char数组进行存储;java9中为byte数组存储;具有不可变性,如果改变就是重新创建一个该对象;
2)可以用作缓冲hash值,作为HashMap的key。其不可变性使得Hash值也不改变;
3)String Pool字符串常量池
在JVM中存放着一个字符串池,其中保存着很多String对象,这些对象可以被共享使用。当以字符串直接创建String对象时,会首先在字符串池中查找是否存在该常量。如果不存在,则在String Pool中创建一个,然后将其地址返回。如果在String Pool中查询到已经存在该常量,则不创建对象,直接返回这个对象地址。Java7之前String Pool被放在运行时常量池中,属于永久代。在java7之后,String Pool被移到堆中,大量使用字符串会导致OutOfMemoryError错误。
使用intern()方法运行将字符添加到String Pool。如果以及存在就直接返回引用,否则就会添加,返回新的引用。
4)安全性,经常作为参数,利用其不可变性。例如作为网络链接参数;
5)线程安全, String 不可变性天生具备线程安全,可以在多个线程中安全地使用。
6)new String(“123”),其中“123”是字面量,编译时期会在String pool创建一个字符串对象指向“123”; 而使用new的方式会在堆中创建一个字符串对象。
7)将一个字符串对象作为另一个字符串对象的构造函数参数时,并不会完全赋值value数组的内容,而是都会指向同一个value数组。
3、StringBuffer和StringBuilder
StringBuffer和StringBuilder具有可变性;StringBuffer线程安全,内部使用synchronized进行同步;StringBuilder线程不安全;
- 参数传递
Java的参数传递是以值进行传递到方法中的,而不是引用传递;
对象作为参数进行传入的时候传入的是地址数据,在两一个方法中进行引用或者改变,对对象本身没有影响;
class Dog{
String name;
Dog(String name){
this.name = name;
}
String getName(){
return this.name;
}
void setName(String name){
this.name=name;
}
String getObjectAdress(){
return super.toString();
}
}
public class Testdata {
public static void main(String[] args) {
Dog dog = new Dog("tony");
System.out.println("1号小狗 "+dog.getObjectAdress()); //1号小狗、2号小狗和4号小狗的地址一样
func(dog);
System.out.println("2号小狗 "+dog.getObjectAdress()); //1号小狗、2号小狗和4号小狗的地址一样
System.out.println("3号小狗 "+dog.getName());
}
private static void func(Dog dog){
System.out.println("4号小狗 "+dog.getObjectAdress()); //1号小狗、2号小狗和4号小狗的地址一样
dog = new Dog("marry");
System.out.println("5号小狗 "+dog.getObjectAdress()); //重新new了一个新对象
System.out.println("6号小狗 "+dog.getName());
}
}
5、不能隐式向下转型
1)double > float 不能直接将double1.1赋值给float 1.1f,不能隐式向下转型。
2)int不能下转型为short类型;int比short精度高;
3)使用 += 或者 ++ 运算符可以执行隐式类型转换。Short s1=1; s1+=1;即为s1=(short)(s1+1);
6、继承
1)类可见表示其他类可以用这个类创建实例对象;
2)成员可见表示其他类可以用这个类的实例对象访问到该成员。
3)protected用于修饰长远,表示在继承体系中成员对于子类可见。
4)子类方法重写父类的方法,那么子类中该方法的访问级别不允许低于父类的访问几倍。
5)字段不能是共有的,公有会导师对字段修改行为失去控制;使用get,set方法对值进行操作;私有类和私有嵌套类是例外。
public class testExamp {
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
} }
- 抽象类用abstract修饰,抽象方法一定要在抽象类中。抽象类不能被实例化;
- 接口成员(字段+方法)默认使用public的,并且不允许定义为private或protected.接口的字段默认都是static和final的。
- 很多情况下,接口优于抽象类,接口没有抽象类严格的类层次结构要求,灵活添加行为,java8之后,接口可以有默认的方法实现。
- Object通用方法
- hashCode():返回散列值,在equals中,等价的对象散列值一定相等,相等的散列值不一定等价。
- Equals()等价,自身与自身是对称的,具有对称性,对任何不是 null 的对象 x 调用 x.equals(null) 结果都为 false。对于基本类型,== 判断两个值是否相等,基本类型没有 equals() 方法。对于引用类型,== 判断两个变量是否引用同一个对象,而 equals() 判断引用的对象是否等价。
- toString()常用
- clone() 是 Object 的 protected 方法,它不是 public,一个类不显式去重写 clone(),其它类就不能直接去调用该类实例的 clone() 方法。通常进行重写。
- finalize() throws Throwable {}垃圾回收机制
6)notify和notifyAll的区别
如果线程调用了对象的 wait()方法,那么线程便会处于该对象的等待池中,等待池中的线程不会去竞争该对象的锁。
当有线程调用了对象的 notifyAll()方法(唤醒所有 wait 线程)或 notify()方法(只随机唤醒一个 wait 线程),被唤醒的的线程便会进入该对象的锁池中,锁池中的线程会去竞争该对象锁。也就是说,调用了notify后只要一个线程会由等待池进入锁池,而notifyAll会将该对象等待池内的所有线程移动到锁池中,等待锁竞争
优先级高的线程竞争到对象锁的概率大,假若某线程没有竞争到该对象锁,它还会留在锁池中,唯有线程再次调用 wait()方法,它才会重新回到等待池中。而竞争到对象锁的线程则继续往下执行,直到执行完了 synchronized 代码块,它会释放掉该对象锁,这时锁池中的线程会继续竞争该对象锁。
6、1)>>向右移动一位,除以2,<<向右移动一位,乘以2;
复合的赋值运算会自动转型,不需要手动转型。Byte a=2; a+=3.14即为a=a+3;
2)a?b :c 的解释:a为真取b,a为假取c;
3)Infinity无穷大 3.14/0
4)NAN 不是个数math.sqrt(-2);
5)Super:访问父类构造方法,访问父类成员,引用父类的方法实现。