Java基础面试题-4

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
上一篇:Java生成6位数验证码


下一篇:java移位运算符对右侧参数进行模运算