Java10个基础题
1: 自增自减运算符
- ++和–运算符可以放在变量之前,也可以放在变量之后,当运算符放在变量之前时(前缀),先自增/减,再赋值;当运算符放在变量之后时(后缀),先赋值,再自增/减
- 例如,当 b = ++a 时,先自增(自己增加 1),再赋值(赋值给 b);当 b = a++ 时,先赋值(赋值给 b),再自增(自己增加 1)。也就是,++a 输出的是 a+1 的值,a++输出的是 a 本身值。
2: 自动装箱与拆箱
- 装箱:将基本类型用它们对应的引用类型包装起来
- 拆箱:将包装类型转换为基本数据类型
- 装箱其实就是调用了 包装类的valueOf()方法,拆箱其实就是调用了 xxxValue()方法。
Integer i = 10; //装箱
int n = i; //拆箱
Integer i = 10 等价于 Integer i = Integer.valueOf(10)
int n = i 等价于 int n = i.intValue();
3: ==和equals比较
- == 比较基本数据类型的时候,比较的是值,引用数据类型比较的是地址(new的对象,==比较永远是false)
- equals:属于Object类的方法,如果我们没有重写过equals方法,那么它就是 ==,但是字符串里面的equals被重写过了,比较的是值
String str1 = "abc";
String str2 = new String("abc");
String str3 = "abc";
String str4 = "xxx";
String str5 = "abc" + "xxx";
String str6 = s3 + s4;
str1 == str2:false
str1.equals(str2):true
str1 == str5:false
str1 == str6:false
str5 == str6:false
str5.equals(str6):true
4: 为什么重写 equals 时必须重写 hashCode 方法?
- 比如在HasMap中,put一个值,则先会计算出其hashCode值,得到对应的索引位置,那么可能该索引位置上已经有值了,那么此时就会调用equals方法,比较两个值是不是一样的。所以重写 equals 时必须重写 hashCode 方法
5: String、StringBuffer、StringBuilder
- String是final修饰的,不可变,每次操作都会产生新的String对象
- StringBuffer是线程安全的,StringBuilder线程不安全的
- 性能:StringBuilder > StringBuffer > String,所以经常需要改变字符串内容时使用前面两个效率会更高
6: 重载和重写的区别
- 重载: 发生在同一个类中,方法名必须相同,参数类型不同、个数不同、顺序不同,方法返回值和访问修饰符可以不同,发生在编译时。
- 重写: 发生在父子类中,方法名、参数列表必须相同,返回值范围小于等于父类,抛出的异常范围小于等于父类,访问修饰符范围大于等于父类;如果父类方法访问修饰符为private则子类就不能重写该方法。
7: 接口和抽象类的区别
- 抽象类可以存在普通成员函数,而接口中只能存在public abstract 方法。
- 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的。
- 抽象类只能继承一个,接口可以实现多个。
8: List和Set的区别
- List:有序,按对象进入的顺序保存对象,可重复,允许多个Null元素对象,可以使用Iterator取出所有元素,在逐一遍历,还可以使用get(int index)获取指定下标的元素
- Set:无序,不可重复,最多允许有一个Null元素对象,取元素时只能用Iterator接口取得所有元素,在逐一遍历各个元素
9: ArrayList和LinkedList区别
- Arraylist 底层使用的是 Object 数组;LinkedList 底层使用的是 双向链表 数据结构
- LinkedList 不支持高效的随机元素访问,而 ArrayList 支持。快速随机访问就是通过元素的序号快速获取元素对象(对应于get(int index)方法)。
- ArrayList 和 LinkedList 都是不同步的,也就是不保证线程安全;
- ArrayList 采用数组存储,所以插入和删除元素的时间复杂度受元素位置的影响;LinkedList 采用链表存储,所以对于add(E e)方法的插入,删除元素时间复杂度不受元素位置的影响
10: continue、break、和 return 的区别是什么?
- continue :指跳出当前的这一次循环,继续下一次循环。
- break :指跳出整个循环体,继续执行循环下面的语句。
- return; :直接使用 return 结束方法执行,用于没有返回值函数的方法
- return value; :return 一个特定值,用于有返回值函数的方法