1.String、StringBuffer 和 StringBuilder 的区别是什么
String
1.实现了序列化Serializable,Comparable以及CharSequence字符序列接口。String是Java字符串对象,底层是基于char字符数组,使用了final修饰类,表示最终类,不能被继承和修改,线程安全。
Serializable接口是启用其序列化功能的接口
Comparable接口是java提供的一个进行排序比较接口
CharSequence是字符序列接口,可以获取指定位置的字符,获取字符串的长度和截取部分字符串的方法
2.每一次对String声明的对象的内容进行修改,得到的都是另外一个新的字符串常量对象,如果字符串常量池中已经存在该字符串常量对象,则不会再创建。
以下链接可以更深入了解string和常量池
3.String重写了Object类中的equals、hashCode方法,重写后equals方法比较了字符串的每一个字符,而重写hashCode方法则是由字符串的每一个字符计算出字符串的hashCode值。
stringbuilder
1.底层继承了AbstractStringBuilder,实现了Serializable、CharSequence接口
2.底层基于char字符数组,可以修改操作对象,非线程安全
3.StringBuilder初始化时默认字节数组初始化容量大小为16,当容量大于当前字节数组容量时会自动进行1倍扩容再加2,每次扩容都会开辟新空间,并且进行新老字符数组的复制。源码底层通过调用System的一个native本地方法arraycopy实现新老字符数组的复制,该native方法底层会直接操作内存,比一般的for循环遍历复制数组的效率要快很多;
4.如果要操作拼接字符串,并且拼接的字符串很长,又没有给StringBuilder指定合适的初始化容量大小,可能会导致底层的字符数组进行多次扩容,多次申请内存空间来完成新老字符数组的复制,性能开销比较大;
stringbuffer
StringBuffer底层实现与StringBuffer最大的区别在于方法使用了synchronized关键字同步,因此是线程安全的,StringBuilder非线程安全。
2.== 和 equals 的区别是什么
== : 它的作用是判断两个对象的地址是不是相等。即判断两个对象是不是同 一个对象。(基本数据类型。== 比较的是值,引用数据类型 == 比较的是内存地址)。
equals() : 它的作用也是判断两个对象是否相等。但它一般有两种使用情况:
情况1:类没有覆盖equals() 方法。则通过 equals() 比较该类的两个对象时, 等价于通过“==”比较这两个对象。
情况2:类覆盖了 equals() 方法。一般,我们都覆盖 equals() 方法来两个对象 的内容相等;若它们的内容相等,则返回 true (即认为这两个对象相等)。
3.hashCode()与equals()的关系
如果两个对象相等,则hashcode一定也是相同的
两个对象相等,对两个对象分别调用equals方法都返回true 两个对象有相同的hashcode值,它们也不一定是相等的
因为内存地址绑定的是原生hashcode,不是封装后的。
4.什么是字符串常量池?
字符串常量池位于堆内存中,专门用来存储字符串常量,可以提高内存的使用率,避免开辟多块空间存储相同的字符串,在创建字符串时 JVM 会首先检查字符串常量池,如果该字符串已经存在池中,则返回它的引用,如果不存在,则实例化一个字符串放到池中,并返回其引用。
5.instanceof 关键字的作用
instanceof 严格来说是Java中的一个双目运算符,是用来测试一个对象是否为一个类的实例,用法为:
boolean result = obj instanceof Class
其中 obj 为一个对象,Class 表示一个类或者一个接口,当 obj 为 Class 的对象,或者是其直接或间接子类,或者是其接口的实现类,结果result 都返回 true,否则返回false。
注意:编译器会检查 obj 是否能转换成右边的class类型,如果不能转换则直接报错,如果不能
确定类型,则通过编译,具体看运行时定。
int i = 0; System.out.println(i instanceof Integer);//编译不通过 i必须是引用类型,不能是基本类型 System.out.println(i instanceof Object);//编译不通过
Integer integer = new Integer(1);
System.out.println(integer instanceof Integer);//true
System.out.println(null instanceof Object); //false ,在 JavaSE规范 中对 instanceof 运算符的规 定就是:如果 obj 为 null,那么将返回 false。
6.Java 序列化中如果有些字段不想进行序列化?
transient 关键字的作用是:阻止实例中那些用此关键字修饰的的变量序列化;当对象被反序列化时,被 transient 修饰的变量值不会被持久化和恢复。transient 只能修饰变量,不能修饰类和方法。
7.final有什么用
用于修饰类、属性和方法;
1.被final修饰的类不可以被继承;
2.被final修饰的方法不可以被重写;
3.被final修饰的变量不可以被改变,被final修饰不可变的是变量的引用,而不是引用指向的内容,引用指向的内容是可以改变的;
8.this与super的区别?
1、super: 它引用当前对象的直接父类中的成员(用来访问直接父类中被隐藏的父类中成员数据或函数,基类与派生类中有相同成员定义时如:super.变量名 super.成员函数据名(实参)
2、this:它代表当前对象名(在程序中易产生二义性之处,应使用this来指明当前对象;如果函数的形参与类中的成员数据同名,这时需用this来指明成员变量名)
3、super()和this()类似,区别是,super()在子类中调用父类的构造方法,this()在本类内调用本类的其它构造方法。
4、super()和this()均需放在构造方法内第一行。
5、尽管可以用this调用一个构造器,但却不能调用两个。
6、this和super不能同时出现在一个构造函数里面,因为this必然会调用其它的构造函数,其它的构造函数必然也会有super语句的存在,所以在同一个构造函数里面有相同的语句,就失去了语句的意义,编译器也不会通过。
7、this()和super()都指的是对象,所以,均不可以在static环境中使用。包括: static变量,static方法,static语句块。
8、从本质上讲,this是一个指向本对象的指针, 然而super是一个Java关键字。