Java基础系列文章
Java基础(一):语言概述 | Java基础(二):原码、反码、补码及进制之间的运算 | Java基础(三):数据类型与进制 | Java基础(四):逻辑运算符和位运算符 |
---|---|---|---|
Java基础(五):流程控制语句 | Java基础(六):数组 | Java基础(七):面向对象编程 | Java基础(八):封装、继承、多态性 |
Java基础(九):Object 类的使用 | Java基础(十):关键字static、代码块、关键字final | Java基础(十一):抽象类、接口、内部类 | Java基础(十二):枚举类 |
Java基础(十三):注解(Annotation) | Java基础(十四):包装类 | Java基础(十五):异常处理 | Java基础(十六):String的常用API |
Java基础(十七):日期时间API | Java基础(十八):java比较器、系统相关类、数学相关类 | Java基础(十九):集合框架 | Java基础(二十):泛型 |
Java基础(二十一):集合源码 | Java基础(二十二):File类与IO流 | Java基础(二十三):反射机制 | Java基础(二十四):网络编程 |
Java基础(二十五):Lambda表达式、方法引用、构造器引用 | Java基础(二十六):Java8 Stream流及Optional类 |
java.lang.Object
是类层次结构的根类,即所有其它类的父类Object
作为超类例如:
public class Person {
...
}
//等价于:
public class Person extends Object {
...
}
值相等
,即为trueint a = 5;
if(a == 6){…}
指向同一个对象
时,==才返回truePerson p1 = new Person();
Person p2 = new Person();
if (p1==p2){…}
Object类源码中equals()的作用与“==”相同
:比较是否指向同一个对象“内容”
是否都相等自定义类重写equal方法
public class User {
private Integer id;
private String username;
private String password;
@Override
public boolean equals(Object o) {
// 如果是同一个对象,直接返回true
if (this == o) {
return true;
}
// 如果传入的对象是null或者不是同一个类,直接返回false
if (o == null || getClass() != o.getClass()) {
return false;
}
// 如果传入的对象是同一个类,所有属性的做比较
User user = (User) o;
return Objects.equals(id, user.id)
&& Objects.equals(username, user.username)
&& Objects.equals(password, user.password);
}
}
练习
int it = 65;
float fl = 65.0f;
System.out.println(“65和65.0f是否相等?” + (it == fl)); // true
char ch1 = 'A'; char ch2 = 12;
System.out.println("65和'A'是否相等?" + (it == ch1)); // true
System.out.println("12和ch2是否相等?" + (12 == ch2)); // true
String str1 = new String("hello");
String str2 = new String("hello");
System.out.println("str1和str2是否相等?"+ (str1 == str2)); // false
System.out.println("str1是否equals str2?"+(str1.equals(str2))); // true
比较两个对象是否相等
hash冲突
,导致有时候值不同,而hashCode是相同的 总结:
实际应用:
效率
,又能保证精准
内存地址转换为整数
,再通过hash函数计算出一个hashCode,由于每个对象的内存地址都不一样,所以哈希码也不一样每个字符的ASCII码的总和
整数的数值
@Data
public class User {
private Integer id;
private String username;
private String password;
public User(Integer id, String username) {
this.id = id;
this.username = username;
}
@Override
public boolean equals(Object o) {
System.out.println("equals...");
// 如果是同一个对象,直接返回true
if (this == o) {
return true;
}
// 如果传入的对象是null或者不是同一个类,直接返回false
if (o == null || getClass() != o.getClass()) {
return false;
}
// 如果传入的对象是同一个类,所有属性的做比较
User user = (User) o;
return Objects.equals(id, user.id)
&& Objects.equals(username, user.username)
&& Objects.equals(password, user.password);
}
@Override
public int hashCode() {
System.out.println("hashCode...");
return Objects.hash(id, username, password);
}
}
// Objects类方法
public static int hash(Object... values) {
return Arrays.hashCode(values);
}
// Arrays类方法
public static int hashCode(Object a[]) {
if (a == null){
return 0;
}
int result = 1;
for (Object element : a){
// 31这个数字是为了尽量的减少hash冲突
result = 31 * result + (element == null ? 0 : element.hashCode());
}
return result;
}
public class Test {
public static void main(String[] args) {
Set<User> set = new HashSet<>();
User u1 = new User(3,"张三");
User u2 = new User(3,"张三");
set.add(u1);
set.add(u2);
System.out.println("set size:"+ set.size());
}
}
输出结果:
hashCode...
hashCode...
equals...
set size:1
“对象的运行时类型 @ 对象的hashCode值的十六进制形式"
Date now = new Date();
System.out.println(“now=” + now); //相当于
System.out.println(“now=” + now.toString());
s1 = "hello";
System.out.println(s1);//相当于System.out.println(s1.toString());
自定义类重写toString方法:
public class Person {
private String name;
private int age;
@Override
public String toString() {
return "Person{" + "name='" + name + '\'' + ", age=" + age + '}';
}
}
Cloneable
接口的类包括赋值的属性及方法
)//Object类的clone()的使用
public class CloneTest {
public static void main(String[] args) {
Animal a1 = new Animal("花花");
try {
Animal a2 = (Animal) a1.clone();
// 原始对象:Animal [name=花花]
System.out.println("原始对象:" + a1);
// clone之后的对象:Animal [name=花花]
System.out.println("clone之后的对象:" + a2);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
class Animal implements Cloneable{
private String name;
public Animal() {
super();
}
public Animal(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Animal [name=" + name + "]";
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
(不是垃圾回收器调用的,是本类对象调用的)
标记为过时
的public class FinalizeTest {
public static void main(String[] args) {
Person p = new Person("Peter", 12);
System.out.println(p);
p = null;//此时对象实体就是垃圾对象,等待被回收。但时间不确定。
System.gc();//强制性释放空间
}
}
class Person{
private String name;
private int age;
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//子类重写此方法,可在释放对象前进行某些操作
@Override
protected void finalize() throws Throwable {
System.out.println("对象被释放--->" + this);
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
不一致
public static void main(String[] args) {
Object obj = new Person();
System.out.println(obj.getClass());//运行时类型
}
结果:
class com.atguigu.java.Person
使用native关键字说明这个方法是原生函数,也就是这个方法是用C/C++
等非Java语言实现的,并且被编译成了DLL
,由Java去调用
为什么要用native方法
native声明的方法,对于调用者,可以当做和其他Java方法一样使用