Java基础面试整理

时间:2024-03-25 10:56:03

1. Java的跨平台优势?

写好的Java源文件通过Javac命令编译生成class文件(中间文件),然后JVM对class文件进行执行生成机器语言然后机器语言在平台中操作,Java在不同的平台下都有对应的不同版本的JVM,JVM可以识别字节码文件从而运行。

2. 简述java中==和equals()的区别。

基本数据之间的比较,==比较的是他们的值。当引用数据类型用==进行比较的时候,比较的是他们在内存中的存放地址。在Object类当中,equals()方法比较数据的内存地址,但是在一些类当中equals()方法会被重写,就会有其他的作用,例如String类首先比较的是两个字符串的地址是否相同,如果相同返回true,如果字符串地址不相同,那么首先会判断要比较的是否属于String类型,如果是,然后在比较里边的内容是否相同。

3. 重载和重写的区别是什么?

重载: 发生在同一个类中,方法名必须相同,参数类型不同、个数不同、顺序不同,方法返回值和访问修饰符可以不同,发生在编译时。

重写: 发生在父子类中,方法名、参数列表必须相同,返回值范围小于等于父类,抛出的异常范围小于等于父类,访问修饰符范围大于等于父类;如果父类方法访问修饰符为 private 则子类就不能重写该方法。

4. 为什么出现方法的重写?

方法的重写来源于继承,继承的本质就是代码的复用。在子类复用父类代码的过程中,难免会有父类的某些方法不适合子类,需要子类进行改造,同时不能破坏父类当中的方法。

5. 重写equals()方法为什么一定要重写hashCode()方法?

Object类当中的equals()方法本质是计较地址是否相等,hashCode()方法是将对象的地址映射为一个int类型的数值。如果我们新建一个类,重写了equals()方法,让它不再单纯地比较对象的地址是否相等,并且不重写hashCode()方法,那么会造成例如hashSet类,存储equals()相等,但是hashCode()不同的对象,那么看起来就违背了hashSet不能存储同一对象的原则。

6. 接口和抽象类的区别?

1.(不能为普通方法提供方法体)接口里只能包含抽象方法,静态方法和默认方法(加default),不能为普通方法提供方法实现,抽象类则完全可以包含普通方法,接口中的普通方法默认为抽象方法。

2 .(public static final 赋值)抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的,并且必须赋值,否则通不过编译。

3 (是否有构造器)接口不能包含构造器,抽象类可以包含构造器,抽象类里的构造器并不是用于创建对象,而是让其子类调用这些构造器来完成属于抽象类的初始化操作

4 .(不能包含初始化块)接口里不能包含初始化块,但抽象类里完全可以包含初始化块。

5. (继承一个抽象类、多个接口)一个类只能继承一个抽象类,而一个类却可以实现多个接口。

1.接口的方法默认是 public,所有方法都是抽象方法,在接口中不能有实现,抽象类可以有非抽象的方法;

2.接口中的实例变量默认是 final 类型的,而抽象类中则不一定;

3.一个类可以实现多个接口,但最多只能继承一个抽象类;

4.一个类实现接口的话要实现接口的所有方法,而抽象类不一定;

5.接口不能用 new 实例化,但可以声明,但是必须引用一个实现该接口的对象 从设计层面来说,抽象类是对类的抽象,是一种模板设计,接口是行为的抽象,是一种行为的规范。

  1. 访问修饰符public、private、protected、以及不写(default默认)时的区别?

public 可以访问所有类;private 只能访问当前类;protected 可以访问当前类,同包,子类,不能访问其他包;不写可以访问当前类和同包。

7. 请简述java 128陷阱。

在Integer的valueOf()方当中,如果数值在-128-127之间,就都存储在一个数组当中,该数组相当于一个缓存,当我们在-128-127之间进行自动装箱的时候,我们就直接返回该值在内存当中的地址,所以在-128-127之间的数值用==进行比较是相等的。而不在这个区间的数,需要新开辟一个内存空间进行装箱,所以用==比较是不相等的。

8. 请简述static关键字。

声明为static的变量称为静态变量类变量。可以直接通过类名引用静态变量,也可以通过实例名来引用静态变量。静态变量是跟类相关联的,类的所有实例共同拥有一个静态变量。声明为static的方法称为静态方法或类方法。静态方法可以直接调用静态方法,访问静态变量,但是不能直接访问实例变量和实例方法。静态方法中不能使用this关键字

9. 请简述final关键字。

final可以用来修饰一个引用,可以用来修饰一个方法,可以用来修饰类。当final修饰方法时,这个方法无法被子类重写。

10. 请简述this关键字。

this调用本类中的属性,也就是类中的成员变量;this调用本类中的其他方法;this调用本类中的其他构造方法,调用时要放在构造方法的首行。

11. 请简述构造器的特点。

(1)可使用的修饰符有public、protected、default、private,不写即为default类型;

(2)名称必须要和类的名称相同;

(3)不能有返回值,void也不行,但允许存在return语句,但return什么也不返回;

(4)参数可有可无,可有一个也可有多个。

12. 简述每一个输出的原因。

public class A {

    public String Show(D obj) {
        return "A and D";
    }

    public String Show(A obj) {
        return "A and A";
    }

}public class B extends A{

    public String Show(Object obj) {
        return "B and B";
    }

    public String Show(A obj) {
        return "B and A";
    }
}
public class C extends B{

}
public class D  extends B{

}
// 测试类
public class Test {
    public static void main(String[] args) {
        A a1 = new A();
        A a2 = new B();
        B b  =  new B();
        C c  =  new C();
        D d  =  new D();
        System.out.println("1---"+a1.Show(b));
        System.out.println("2---"+a1.Show(c));
        System.out.println("3---"+a1.Show(d));

        System.out.println("4----"+a2.Show(b));
        System.out.println("5----"+a2.Show(c));
        System.out.println("6----"+a2.Show(d));

        System.out.println("7---"+b.Show(b));
        System.out.println("8---"+b.Show(c));
        System.out.println("9---"+b.Show(d));
    }
}  

1--A and A(b向上转型成a)

2--A and A(c向上转型成a)

3--A and D(方法直接调用)

4--B and A(b向上转型成a)

5--B and A(c向上转型成a)

6--A and D(方法直接调用)

7--B and A(b向上转型成a)

8--B and A(c向上转型成a)

9--A and D(方法直接调用)

a2能调用的方法为showD和showA: a2是A类型的对象,newB的时候创建出了A的两个对象,a2只能使用A对象里面的方法,但是原来的showA被子类的方法覆盖,所以只能调用showD和showB两个方法。

13. 简述以下程序的输出并说明原因。

    public static void main(String[] args) {
        int  a = 10;
        int  b = 10;
        Integer a1 = 10;
        Integer b1 = 10;
        Integer a2 = new Integer(10);
        Integer b2 = new Integer(10);
        System.out.println(a == b); 
        System.out.println(a1 == b1); 
        System.out.println(a2 == b2); 
        System.out.println(a1 == a); 
        System.out.println(a1.equals(a)); 
        System.out.println(a1 == a2);
        System.out.println(a == a2); 
    }
}

true(基本数据类型 == 比较值)

true(在Integet的valueOf()方当中,如果数值在-128-127之间,就都存储在一个数组当中,该数组相当于一个缓存,当我们在-128-127之间进行自动装箱的时候,我们就直接返回该值在内存当中的地址,所以在-128-127之间的数值用==进行比较是相等的。)

false(引用数据类型 == 比较地址)

true(用 == 判断,自动拆箱)

true(用equals() 判断,自动装箱)

false(==比较地址)

true(a2自动拆箱)