1、字符常量和字符串常量的区别
- 字符常量用单引号,字符串常量用双引号。
- 字符常量只有一个字符,字符串常量可以有多个字符。
- 字符常量占两个字节,字符串常量占多个字节。
2、构造器Constructor是否可以被override?
- Constructor不能被override(重写),但是可以被overload(重载)
3、重写和重载的区别
- 重写
- 重写发生在子类,继承父类,重新处理返回结果。以此来实现多态性。
- 重写参数和方法名称不能变,需与父类一致。
- 重写的返回类型应比父类更小或者相等。
- 重写的异常类型应比父类更小或者相等。
- 相等或者更低限制的修饰符
- 发生在运行期
- 重载
- 在同一个类里,同一个方法,不同的参数。 实现多态性。
- 返回类型可修改
- 异常抛出可修改
- 访问修饰符可修改
- 发生在编译期
4、java三大特性,封装、继承和多态
- 封装 把对象私有化,同时提供一些对外访问的方法,让外部可以进行访问。
- 继承 子类继承父类,重新实现父类方法。
- 多态 继承和接口实现多态,实现同一方法不同的处理过程和相同的处理结果。
5、String、StringBuilder和StringBuffer有什么区别
- String底层用final修饰字符数组来保存字符串,private final char value[] 所以String是不可变的。(jdk9后,改成用byte数组来存储字符串)
- StringBuilder和StringBuffer都继承AbstractStringBuilder类,也是用字符数组保存字符串,但是没有final,所以是可变的。StringBuffer的方法加了同步锁,所以线程安全,相对效率也会慢于非线程安全的StringBuilder。
6、自动装箱和自动拆箱
- 装箱,将基本类型用他们的引用类型包装起来。例如 Intger t = 99;实际执行了Integer t = Integer.valueOf(99);
- 注:当t<128时,使用的是创建好的SMALL_VALUES[]数组的Integer,当>=128时,使用的是new Integer(t),新建对象会导致物理地址不同;
- Integer派别:Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的。
Double派别:Double、Float的valueOf方法的实现是类似的。每次都返回不同的对象。
Boolean每次都返回相同的对象。
- 拆箱,将包装类型转换成基本类型。例如 int tp = t; 实际执行了 int tp = t.intValue();
7、静态方法内调用非静态成员为什么是非法的?
- 因为静态方法可以不通过新建对象来调用,因此在静态方法里,不能调用非静态变量,也不可以访问非静态变量成员。
8、java中无参且不做事的构造方法的作用
- 新建对象时可以不用带参数;
- 继承父类,如父类没有无参数构造,那子类也不能使用无参数构造,且子类只能通过super()来实现父类的有参构造。
9、接口和抽象类的区别
- 接口
- 一个类可以实现多个接口
- 所有方法不能有实现代码,只能是抽象方法(jdk1.7以及之前版本,1.8引入静态方法和默认方法,1.9引入私有静态方法和私有方法)
- 方法默认修饰符为public
- 接口中除了final,static外,不能有其他变量
- 是一种行为规范
- 抽象类
- 可以有非抽象方法,实现代码
- 抽象类可以有多种变量
- 一个类只能实现一个抽象类
- 抽象方法可用修饰符public、protected、default,不能使用private,因为抽象方法要被重写
- 抽象类是一种模版设计的应用
- 注:jdk8接口新特性,可定义静态方法(static)和默认方法(default);同时实现两个接口,包含相同的默认方法时,需重写默认方法,否则会报错。
- jdk9接口引入私有静态方法和私有方法
10、成员变量和局部变量的区别
成员变量 | 局部变量 |
类中的变量 | 方法中的变量或者参数 |
可以被修饰符修饰,public private static final | 只能被final修饰符修饰 |
static修饰的是属于类的,没有static修饰属于实例对象的 | 基本数据类型存于栈内;引用数据类型存于堆内或指向常量池中的地址 |
随对象创建而存在 | 随方法调用结束而消失 |
没有赋值会自动赋默认值;final修饰的成员变量必须显式赋值 | 不会自动赋值,需调用传入,或者手动赋值 |
11、创建对象用什么运算符,对象实体和对象引用的区别?
- 创建对象用new运算符,new对象的实例在堆内存中,对象引用指向对象实例(对象引用放入栈内存中)。例如:Integer i = new Integer(10); i的对象实例放在堆内存中,i = 10的对象引用放入栈内存中并指向i的实例对象。
Integer i1 = new Integer(10); Integer i2 = new Integer(10); System.out.println(i1 == i2); //false 使用对象实例比较,比较物理空间地址是否相同,新建了两个实例,分配了两个物理空间 System.out.println(i1.intValue() == i2.intValue()); //true 使用对象引用比较,比较值是否相等
- 一个对象引用只能指向0个(String s = "123";没有创建对象,直接引用)或者1个对象(String s = new String("123"),创建对象和对象引用);一个对象可以被多个对象引用指向(String s1 = new String("1231"); String s2 = s1;这个时候s1和s2的对象引用指向同一个对象实例)。
12、方法的返回值。
- 当调用方法需要获取结果时,需设置对应结果的返回类型,public String menthod(){ return String;};如不需要返回结果,可使用 void。
13、一个类的构造方法有什么用?可以不构造方法吗?有什么特性
- 构造方法可以初始化需要使用的参数。
- 不构造方法也可以正常运行,系统会默认构造一个无参的方法。
- ①、名字和类名相同;②、没有返回值,不能用void方法声明构造;③、创建对象时,自动执行,无需调用。
14、静态方法和实例方法有什么不同
- 静态方法可以直接通过类型.静态方法名调用,只能访问静态的本类成员变量和方法;实例需要创建对象后,通过实例对象调用,可以访问所有的本来成员变量和方法。
15、子类方法,构造方法,初始化方法,父类方法,构造方法,初始化方法的调用顺序?
- 父类初始化>父类构造>子类初始化>子类构造>调用方法
16、==和equals
- ==比较的是物理地址是否相等;当比较对象是基本数据类型时,比较值是否相等;当比较对象是引用数据类型时,比较物理地址是否相同。
- equals比较的是常量池中的值是否相等。注:看equals方法是否重写过,String的equals方法被重写过比较值相等;object的equals方法没有被重写过等同于==,比较物理地址是否相同。
17、hashCode和equals
- hashCode是哈希码,也叫散列码;实际上返回的是int整数。用来确认对象在哈希表中索引的位置。散列表存储的是键值对,根据键快速的检索出对应的值。
- 为什么会有hashCode;我们用HashSet检查重复为例;对象存入HashSet时,HashSet先获取对象的hashCode值来判断加入的位置,会与其他已存入的数据的hashCode作比较,没有相同的就代表该对象没有出现过;当出现相同就会调用equals来判断对象是否相同,相同则不加入;不相同则重新散列到其他位置。这样减少了equals的次数,提升速度。
- 为什么重写equals,一定要重写hashCode?因为两个对象相等,那hashCode也一定相等。当重写了equals方法,即改变了原比对方法,所以hashCode也必须重写来适用当前的equals方法,以达到equals相等,hashCode也相等的效果。
@Override public int hashCode() { int result = 17; result = 31 * result + (name == null ? 0 : name.hashCode()); result = 31 * result + (age == null ? 0 : age.hashCode()); return result; }
- 为什么hashCode相等,对象也不一定相等?因为hashCode使用的是杂凑算法,容易导致hash碰撞(不同对象得到相同的hash值称为hash碰撞),所以hashCode相等,对象不一定相等。例如:
String s1 = new String("abc"); String s2 = "a"+"bc"; System.out.println(s1 == s2); //false System.out.println(s1.hashCode() == s2.hashCode()); // true
18、为什么java中只有值传递?
- java程序设计语言总是采用按值调用,方法得到的只是对象参数的拷贝。
- 按值调⽤ (call by value)表示⽅法接收的是调⽤者提供的值,⽽按引⽤调⽤(call by reference)表示⽅法 接收的是调⽤者提供的变量地址。⼀个⽅法可以修改传递引⽤所对应的变量值,⽽不能修改传递 值调⽤所对应的变量值。
- 一个方法不能修改基本数据类型参数(整形和布尔型)
- 一个方法可以改变一个对象的参数状态
- 一个方法不能让对象参数引用一个新的对象