String的所有方法和参数都是用final修饰的,是不可变的。java中双引号括起来的字符串,例如"abc","qwe"都是存储在方法区中的字符串常量池的。
此时字符串常量池中会创建"abc"这个字符串常量,new创建的所有对象都在堆内存中,此时堆中存放的是指向“字符串常量池”的内存地址,所以s1==s2为false,他们两个在堆中的地址不同。
栈中存放的是指向堆的引用地址
String s1 = new String("abc");
String s2 = new String("abc");
System.out.println(s1==s2); false 比较地址
System.out.println(s1.equals(s2)); true 比较内容
StringBuilder 和 Stringbuffer 都是在原对象上操作,StringBuffer是线程安全的,StringBuilder是线程不安全的,因为StringBuffer的方法都是synchronized修饰的。
性能:StringBuilder > StringBuffer > String
使用场景:经常需要改变字符串内容时,不用String,优先使用StringBuilder,多线程共享变量时使用StringBuffer
注意: 千万不能说不考虑性能时用StringBuffer 不考虑线程安全时使用StringBuilder,因为没有程序是不考虑这两个的
重载:发生在同一个类中,方法名相同,参数类型不同、个数不同、顺序不同。
注意:方法名和参数都相同,只有返回值或访问修饰符不同时,不是重载!编译会报错 public String add(int i); public int add(int i); 编译报错,不是重载,重载和返回值修饰符没关系
重写:发生在父子类中,方法名、参数列表必须相同,返回值范围小于等于父类,抛出的异常范围小于等于父类,访问修饰符范围大于等于父类;如果父类方法用private修饰,则子类无法重写也无法继承
3、接口和抽象类的区别1、抽象类中可以有普通的成员函数,但是接口中只能存在public abstract方法。
2、抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的。
3、抽象类只能继承一个,接口可以实现多个。
抽象类和接口是不可以直接实例化的,若要实例化,就只能实例化时实现里面的抽象方法。
接口的设计目的:对类的行为进行约束,强制不同的类要具有相同的行为。它只约束了行为的有无,不对如何实现行为进行限制。
抽象类的设计目的:是代码复用。当不同的类具有相同的行为,且其中一部分行为的实现方式一致时,可以让这些类都派生于一个抽象类。先有子类,然后再有抽象父类
使用场景:当关注一个事务本质的时候,用抽象类;当关注一个操作的时候,用接口。
但是抽象类的代价高,因为每个类只能继承一个类,而可以实现多个接口。
equals如果不重写,那么就使用Object中的equals,即 == 比较引用地址
hashCode是为了计算哈希值返回int型,计算hashCode()是为了放入哈希表中,两个对象hashCode()相同,值不一定相同。两个对象相等,那么hashCode()一定相同。
hashCode()默认行为时对堆上的对象产生独特值。如果没有重新hashCode(),那么同一个类的两个对象无论如何也不会相等(即使两个对象指向相同的数据)。



