13、抽象类和接口有什么区别?
(1)抽象类中可以定义构造函数,接口不能定义构造函数;
(2)抽象类中可以有抽象方法和具体方法,而接口中只能有抽象方法(public abstract);
(3)抽象类中的成员权限可以是public、default、protected(抽象类中抽象方法就是为了重写,所以不能用private修饰);而接口中的成员只可以是public(方法默认:public abstract、成员变量默认:public static final);
(4)抽象类中可以包含静态方法,而接口中不可以包含静态方法;
JDK 8中的改变:
(1)在JDK8中,允许在接口中包含带有具体实现的方法,使用default修饰,这类方法就是默认方法。
(2)在JDK8中,接口可以包含静态方法(之前不可以包含静态方法是因为,接口不能实现方法,只可以定义方法,而静态方法必须实现在接口中。)现在可以包含了,也只能直接用接口调用静态方法。但仍然不可以包含静态代码块。静态方法与.class 文件相关,只能使用接口名调用,不可以通过实现类的类名或者实现类的对象调用。
14、静态变量和实例变量的区别?
静态变量:是被static修饰的变量,也称为类变量,它属于类,因此不管创建多少对象,静态变量在内存中有且仅有一个拷贝;静态变量可以实现让多个对象共享内存。
实例变量:属于某一实例,需要先创建对象,然后通过对象才能访问到它。
15、short s1 = 1; s1 = s1+1;有什么错?short s1 = 1; s1 += 1;呢?
对于short s1 = 1; s1 = s1+1;来说,在s1+1运算时会自动提升表达式的类型为int,那么将int型值赋值给short型变量,s1会出现类型转换错误。
对于short s1 = 1; s1 += 1;来说,+=是Java语言规定的运算符,Java编译器会对它进行特殊处理,因此可以正确编译。
16、Integer和int的区别?
(1)int是Java的八种基本数据类型之一,而Integer是Java为int类型提供的封装类;
(2)int型变量的默认值是0,Integer变量的默认值是null;
(3)Integer变量必须实例化后才可以使用,而int不需要;
Integer和int的比较延申:
(1)由于Integer变量实际上是对一个Integer对象的饮用,所以两个通过new生成的Integer变量永远是不相等的,因为其内存地址是不同的;
(2)Integer变量和int变量比较时,只要两个变量的值是相等的,则结果为true。因为包装类Integer和基本数据类型int类型进行比较时,Java会自动拆包类为int,然后进行比较,实际上就是两个int型变量进行比较;
(3)非new生成的Integer变量和new Integer() 生成的变量进行比较时,结果为false。因为非new生成的Integer变量指向的是Java常量池中的对象,而new Integer() 生成的变量指向堆中新建的对象,两者在内存中的地址不同;
(4)对于两个非new生成的Integer对象进行比较时,如果两个变量的值在区间[-128,127]之间,则比较结果为true,否则为false。Java在编译Integer i = 100时,会编译成Integer i = Integer.valueOf(100), 而Integer类型的源码如下所示:
public static Integer valueOf(int var0) {
return var0 >= -128 && var0 <= Integer.IntegerCache.high ?
Integer.IntegerCache.cache[var0 + 128] : new Integer(var0);
}
从上面的代码中可以看出:Java对于[-128,127]之间的数会进行缓存,比如:Integer i = 127,会将127进行缓存,下次再写Integer j = 127时,就会从缓存中取出,而对于这个区间之外的数就需要new了。
包装类的缓存:
Boolean:全部缓存
Byte:全部缓存
Character:<= 127 缓存
Short:-128 — 127 缓存
Long:-128 — 127 缓存
Integer:-128 — 127 缓存
Float:没有缓存
Double:没有缓存
17、自动装箱与自动拆箱
自动装箱是Java编译器在基本数据类型和对应的包装类之间做的一个转换。例如:将int转换成Integer、double转换成Double等等。反之则为自动拆箱。
Integer i = 10; //装箱
int n = i; //拆箱
基本数据类型:boolean、char、byte、short、int、long、float、double
封装类型:Boolean、Character、Byte、Short、Integer、Long、Float、Double
valueOf()方法(装箱)
语法:
static Integer valueOf(int i)
static Integer valueOf(String s)
static Integer valueOf(String s, int radix)
参数:
- i -- Integer 对象的整数。
- s -- Integer 对象的字符串。
- radix --在解析字符串 s 时使用的进制数,用于指定使用的进制数。
返回值:
- Integer valueOf(int i):返回一个表示指定的 int 值的 Integer 实例。
- Integer valueOf(String s):返回保存指定的 String 的值的 Integer 对象。
- Integer valueOf(String s, int radix): 返回一个 Integer 对象,该对象中保存了用第二个参数提供的基数进行解析时从指定的 String 中提取的值。
实例
public class Test{
public static void main(String args[]){
Integer x =Integer.valueOf(9);
Double c = Double.valueOf(5);
Float a = Float.valueOf("80");
Integer b = Integer.valueOf("444",16); // 使用 16 进制
System.out.println(x);
System.out.println(c);
System.out.println(a);
System.out.println(b);
}
}
编译以上程序,输出结果为:
9
5.0
80.0
1092
注意:
在这里只解释一下为什么Double类的valueOf方法会采用与Integer类的valueOf方法不同的实现。很简单:在某个范围内的整型数值的个数是有限的,而浮点数却不是。
Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的。
Double、Float的valueOf方法的实现是类似的。
xxxValue()方法(拆箱)
xxxValue() 方法用于将 Number 对象转换为 xxx 数据类型的值并返回。
相关的方法有:
类型 | 方法及描述 |
---|---|
byte | byteValue() :以 byte 形式返回指定的数值。 |
abstract double | doubleValue() :以 double 形式返回指定的数值。 |
abstract float | floatValue() :以 float 形式返回指定的数值。 |
abstract int | intValue() :以 int 形式返回指定的数值。 |
abstract long | longValue() :以 long 形式返回指定的数值。 |
short | shortValue() :以 short 形式返回指定的数值。 |
参数:
以上各函数不接受任何的参数。
返回值:
转换为 xxx 类型后该对象表示的数值。
实例
public class Test{
public static void main(String args[]){
Integer x = 5;
// 返回 byte 原生数据类型
System.out.println( x.byteValue() );
// 返回 double 原生数据类型
System.out.println(x.doubleValue());
// 返回 long 原生数据类型
System.out.println( x.longValue() );
}
}
编译以上程序,输出结果为:
5
5.0
5