文章目录
前言
今天是更新第 2 天,今天的主要内容还是 Java基础
正文
1. Object 类都有哪些方法
这里只列举方法,重点是前 5 个,具体是做什么的就不一一解释了。
- 无参构造方法
- equals()
- hashCode()
- toString()
- finalize()
- clone()
- getClass()
- wait()
- notify()
- 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;
}
}