「持续100 天更新 Java 相关面试题」—— 第 2 天

前言

今天是更新第 2 天,今天的主要内容还是 Java基础

正文

1. Object 类都有哪些方法

这里只列举方法,重点是前 5 个,具体是做什么的就不一一解释了。

  1. 无参构造方法
  2. equals()
  3. hashCode()
  4. toString()
  5. finalize()
  6. clone()
  7. getClass()
  8. wait()
  9. notify()
  10. notifyAll()

2. == 和 equals() 的区别

  • == 可以判断基本数据类型也可以判断引用数据类型,判断基本数据类型时,是判断值是否相等(==两边只要一个是基本数据类型,判断的就是值是否相等)。判断引用类型时,是判断两个引用是否指向同一个地址
  • equals 只能判断引用数据类型,默认判断的是两个引用是否指向同一个地址,子类往往重写此方法,用于判断里边的内容是否相等

3. Java 的继承机制

Java是不支持多继承的,在Java语言中,子类最多只能继承一个父类。

4. hashCode() 和 equals() 之间的区别,为什么重写了equals()方法后还要重写hashCode()方法?

区别:

// Object 类的hashCode()方法和equals()方法
public class Object {
	public native int hashCode();
    
    public boolean equals(Object obj) {
        return (this == obj);
    }
}

hashCode() 作用是获取哈希码,这个哈希码的作用是确定该对象在哈希表中的索引位置,提高具有哈希结构的容器的效率。

equals() 作用是判断两个对象是否是否指向同一个地址,通常子类会重写equals方法用于判断两个对象的内容是否相等

  • 两个对象相等,则hashcode一定也是相同的

  • 两个对象相等,对两个对象分别调用equals方法都返回true

  • 两个对象有相同的hashcode值,它们不一定是相等的

  • 如果没有重写hashCode(),同一个类的不同对象的哈希值不相等(即使这两个对象指向相同的数据)

    // 没有重写 hashCode() 方法
    public class Main {
        public static void main(String[] args){
            Student s1 = new Student("one",21);
            Student s2 = new Student("one",21);
    
            System.out.println("s1 ==> " + s1.hashCode()); // s1 ==> 460141958
            System.out.println("s2 ==> " + s2.hashCode()); // s2 ==> 1163157884
        }
    }
    
    // Student 类
    class Student {
        public String name;
        public int age;
    
        public Student(String name, int age) {
            this.name = name;
            this.age = age;
        }
    }
    
    // 重写 hashCode() 后
    import java.util.Objects;
    
    public class Main {
        public static void main(String[] args){
            Student s1 = new Student("one",21);
            Student s2 = new Student("one",21);
            Student s3 = new Student("two",21);
    
            System.out.println("s1 ==> " + s1.hashCode()); // s1 ==> 3416624
            System.out.println("s2 ==> " + s2.hashCode()); // s2 ==> 3416624
            System.out.println("s3 ==> " + s3.hashCode()); // s3 ==> 3574538
        }
    }
    
    // Student 类
    class Student {
        public String name;
        public int age;
    
        public Student(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Student student = (Student) o;
            return age == student.age && Objects.equals(name, student.name);
        }
    
        @Override
        public int hashCode() {
            return Objects.hash(name, age);
        }
    }
    

    如果我们只需要对比两个对象内容是否相同,只重写 equals 即可。但在散列表中,我们需要基于哈希值算出元素要插入的数组下标,如果该下标已经有值,说明发生了哈希冲突,这时我们再调用 equals 进行进一步的对比。为了让同一个类的内容相同的不同对象视为相等的,就必须重写 hashCode 方法。

5. 方法重写和方法重载的区别

  • 方法重载: 发生在同一个类中,方法名必须相同,参数类型、个数、顺序至少有一个不同,方法返回值和访问修饰符不做限制。

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

    名称作用范围方法名形参列表返回类型访问修饰符
    方法重载同一个类必须相同参数类型、个数、顺序至少有一个不同不做限制不做限制
    方法重写父子类必须相同参数列表必须相同小于等于父类大于等于父类

6.final 关键字

修饰类:表示类不可被继承

修饰方法:表示方法不可被子类重写,但是可以重载

修饰变量:表示变量一旦被赋值就不可以更改它的值。

修饰变量的几种情况:

  • final修饰静态变量:只能在静态代码块中指定初始值或者声明该类变量时指定初始值。
  • final修饰成员变量:可以在普通代码块、声明该变量时或者构造器中指定初始值。
  • final修饰局部变量:系统不会为局部变量进行初始化,局部变量必须显式初始化。因此使用final修饰局部变量时,既可以在定义时指定默认值,后面的代码不能对变量再赋值,也可以不指定默认值,而在后面的代码中对final变量赋初值(仅一次)
  • 修饰基本数据类型和引用数据类型,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。但是内部元素的值是可变的。
import java.util.Arrays;

public class Main {
    public static void main(String[] args){
        final int[] arr = new int[5];
        arr[0] = 10;
        // [10, 0, 0, 0, 0]
        System.out.println(Arrays.toString(arr));  
        arr[0] = 20;
        // [20, 0, 0, 0, 0]
        System.out.println(Arrays.toString(arr)); 

        int[] a = {1, 2, 3, 4, 5};

        // idea报错:java无法为最终变量arr分配值 Cannot assign a value to final variable 'arr'
        arr = a;
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值