Java中Object类的理解和使用

 更新时间:2023年06月28日 10:32:54   作者:码农高飞  
Object类是java.lang包下的核心类,Object类是所有类的父类,何一个类时候如果没有明确的继承一个父类的话,那么它就是Object的子类,本文将通过代码示例详细介绍一下Java中Object类的理解和使用,需要的朋友可以参考下

如何理解根父类

java.lang.Object是类层次结构的根类,即所有其它类的父类。每个类都使用Object作为超类。

  • Object类型的变量与除Object以外的任意引用数据类型的对象都存在多态引用
method(Object obj){…} //可以接收任何类作为其参数
Person o = new Person();  
method(o);
  • 所有对象(包括数组)都实现这个类的方法
  • 一个类没有特别指定父类,那么默认则继承自Object类
public class Person {
	...
}
//上面和下面是等价的
public class Person extends Object {
	...
}

Object类的方法

根据JDK源代码及Object类的API文档,Object类中包含的方法有11个,但是今天只看其中主要的5个。

equals()

所有类都继承了Object,那么也就获得了equals()方法,且还可以重写方法。 equals():

  • 只能比较引用类型,比较是否指向同一个对象
  • 格式:obj1.equals(obj2)
  • 特例:当用equals()方法进行比较时,对类File、String、Date及包装类来说,是比较类型及内容而不考虑引用的是否是同一个对象,因为在这些类中重写了Object类的equals()方法
  • 当自定义equals()方法时,可以重写方法,用来比较两个对象的内容是否一样

重写equals()方法的原则:

  • 对称性:如果x.equals(y)返回是true,那么y.equals(x)也应该返回是true
  • 自反性:x.equals(x)必须返回是true
  • 传递性:如果x.equals(y)返回是true,且y.equals(z)返回是true,那么z.equals(x)也应该返回true
  • 一致性:如果x.equals(y)返回是true,只要x和y内容不变,无论重复x.equals(y)多少次,都是返回true
  • 任何情况下,x.equals(null)都是返回false,x.equals(和x是不同类型的对象)都是返回false

重写举例:

class User{
	private String host;
	private String username;
	private String password;
	public User(String host, String username, String password) {
		super();
		this.host = host;
		this.username = username;
		this.password = password;
	}
	public User() {
		super();
	}
	public String getHost() {
		return host;
	}
	public void setHost(String host) {
		this.host = host;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	@Override
	public String toString() {
		return "User [host=" + host + ", username=" + username + ", password=" + password + "]";
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		User other = (User) obj;
		if (host == null) {
			if (other.host != null)
				return false;
		} else if (!host.equals(other.host))
			return false;
		if (password == null) {
			if (other.password != null)
				return false;
		} else if (!password.equals(other.password))
			return false;
		if (username == null) {
			if (other.username != null)
				return false;
		} else if (!username.equals(other.username))
			return false;
		return true;
	}
}

= =:

  • 基本类型比较的是值:只要两个变量的值相等,即为true
  • 引用类型比较引用(是否指向同一个对象):只有指向同一个对象时,才返回true

注意: 用来进行比较时,符号两边的数据类型必须兼容(可自动转换的基本数据类型除外),否则编译报错。

= =和equals的区别:

  • = =即可以比较基本数据类型也可以比较引用类型,对于基本类型就是比较数值,对于引用类型就是比较内存地址
  • equals是属于java.lang.Object类里面的方法,如果该方法没有被重写,默认也是= =,String等类的equals方法是被重写过的,而且String类在日常开发中用的较多,形成了equals是比较值的错误观点,这点要注意
  • 具体要看自定义类型里有没有重写Object的equals方法来判断
  • 通常情况下,重写equals方法,会比较类中的相应属性是否都相等

toString()

public String toString():默认情况下toString()返回的是对象的运行时类型@对象的hashCode值的十六进制形式。

在进行String与其他类型数据的连接操作时,自动调用toString方法,比如:

Date now=new Date();
System.out.println("now="+now); //相当于"now="+now.toString()

如果直接打印对象,默认会调用该对象的toString()方法(Java的引用数据类型的变量中存储的实际上是对象的内存地址,但是Java对外隐藏了内存地址信息,所以不能直接将内存地址显示出来,所以当打印对象时,JVM会调用对象的toString()方法)。

可以根据需要在用户自定义类型中重写toString()方法。

getClass()

public final Class<?> getClass():获取对象的运行时类型。

由于Java有多态现象,所以一个引用数据类型的变量编译时类型与运行时类型可能不一致,因此如果需要查看这个变量实际指向的对象的类型,就需要用getClass()方法。

public static void main(String[] args) {
	Object obj = new Person();
	System.out.println(obj.getClass()); //获取运行时类型
}

hashCode()

public int hashCode():返回每个对象的hash值。

如果重写equals,那么通常会一起重写hashCode()方法,hashCode()方法主要是为了当对象存储到哈希表等容器中时提高存储和查询性能用的,这是因为关于hashCode()有两个常规协定:

  • 如果两个对象的hash值不同,那么这两个对象一定不相等
  • 如果两个对象的hash值是相同的,那么这两个对象不一定相等

重写equals()和hashCode()方法时,要保证满足如下要求:

  • 如果两个对象调用equals返回true,那么要求这两个对象的hashCode值一定是相等的
  • 如果两个对象的hashCode值不同,那么要求这两个对象调用equals方法一定是false
  • 如果两个对象的hashCode值相同,那么这两个对象调用equals可能是true,也可能是false
public static void main(String[] args) {
	System.out.println("Aa".hashCode()); //2112
	System.out.println("BB".hashCode()); //2112
}

clone()

clone()方法将对象复制了一份并返回给调用者,clone()的作用在于复制对象,在复制对象的过程中,首先要分配一个和源对象同样大小的空间,在这个空间中创建一个新的对象。

示例:

public class CloneTest {
	public static void main(String[] args) {
		Animal a1 = new Animal("小黑");
		try {
			Animal a2 = (Animal) a1.clone();
			System.out.println("原始对象:" + a1);
			a2.setName("小黄");
			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();
	}
}

finalize()

当对象被回收时,系统自动调用该对象的finalize()方法,子类可以重写该方法,做一些释放资源的操作。如果重写该方法,让一个新的引用变量重新引用该对象,则会重新激活对象。

永远不要主动调用某个对象的finalize方法,应该交给垃圾回收机制调用。

什么时候被回收:

当某个对象没有任何引用时,JVM就认为这个对象是垃圾对象,就会在之后不确定的时间使用垃圾回收机制来销毁该对象,在销毁该对象前,会先调用finalize()方法(垃圾回收发生具有不可预知性,程序无法精确控制垃圾回收机制的执行)。

垃圾回收机制的调用是由系统来决定的,也可以通过System.gc()或者Runtime.getRuntime().gc()来通知系统进行垃圾回收,会有一些效果,但是系统是否进行垃圾回收依然是不确定的。

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 + "]";
	}
}

native关键字的理解

使用native关键字说明这个方法是原生函数,也就是这个方法是用c/c++等非Java语言实现的,并且被编译成了dll,由Java去调用,在定义一个native方法时,并不提供实现体。

为什么要用native方法

虽然Java使用起来非常方便,然而有些层次的任务用Java实现起来不易,或对程序的效率很在意时就会考虑native方法。

例如:有时Java应用需要与Java外面的环境交互,这是本地方法存在的主要原因,当Java需要与一些底层系统如操作系统或某些硬件交换信息时的情况,本地方法正是这样的一种交流机制,它提供了一个非常简洁的接口,而且无需我们去了解Java应用之外的繁琐细节。

native声明的方法,对于调用者可以当做其他Java方法一样使用

一个native方法可以返回任何Java类型,包括非基本类型,而且同样可以进行异常控制。

native方法的存在并不会对其他类调用这些本地方法产生任何的影响,实际上调用这些方法的其他类甚至不知道它调用的是一个本地方法,JVM将控制调用本地方法的所有细节。

如果一个含有本地方法的类被继承,子类会继承这个本地方法并且可以用Java在需要的时候重写该方法。

以上就是Java中Object类的理解和使用的详细内容,更多关于Java Object类的资料请关注脚本之家其它相关文章!

相关文章

  • JAVA操作MongoDB数据库实例教程

    JAVA操作MongoDB数据库实例教程

    MongoDB是一个文档型数据库,是NOSQL家族中最重要的成员之一,下面这篇文章主要给大家介绍了关于JAVA操作MongoDB数据库的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-05-05
  • 在SpringBoot中该如何配置拦截器

    在SpringBoot中该如何配置拦截器

    今天给大家带来的是关于SpringBoot的相关知识,文章围绕在SpringBoot中该如何配置拦截器展开,文中有非常详细的介绍及代码示例,需要的朋友可以参考下
    2021-06-06
  • Java二维数组计算集合总结

    Java二维数组计算集合总结

    本篇文章给大家整理了关于Java二维数组计算集合的内容总结,有需要的读者们可以参考下。
    2018-02-02
  • java 集合之实现类ArrayList和LinkedList的方法

    java 集合之实现类ArrayList和LinkedList的方法

    下面小编就为大家带来一篇java 集合之实现类ArrayList和LinkedList的方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10
  • 解析Tars-Java客户端源码

    解析Tars-Java客户端源码

    Tars是基于名字服务使用Tars协议的高性能RPC开发框架,同时配套一体化的服务治理平台,帮助个人或者企业快速的以微服务的方式构建自己稳定可靠的分布式应用
    2021-06-06
  • Spring循环依赖之问题复现详解

    Spring循环依赖之问题复现详解

    这篇文章主要为大家详细介绍了Spring的循环依赖什么时候会出现以及如何解决循环依赖,文中的示例代码讲解详细,感兴趣的可以学习一下
    2022-07-07
  • Springboot整合mybatis开启二级缓存的实现示例

    Springboot整合mybatis开启二级缓存的实现示例

    在一级缓存中,是查询两次数据库的,显然这是一种浪费,既然SQL查询相同,就没有必要再次查库了,直接利用缓存数据即可,这种思想就是MyBatis二级缓存的初衷,本文就详细的介绍了Springboot整合mybatis开启二级缓存,感兴趣的可以了解一下
    2022-05-05
  • java实现KFC点餐系统

    java实现KFC点餐系统

    这篇文章主要为大家详细介绍了java实现KFC点餐系统,模拟肯德基快餐店的收银系统,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-01-01
  • SpringBoot整合Redis实现token缓存

    SpringBoot整合Redis实现token缓存

    于token通常会被多次使用,我们需要把它保存到缓存中,以减少频繁地访问数据库,本文主要介绍了SpringBoot整合Redis实现token缓存,感兴趣的可以了解一下
    2024-02-02
  • Spring数据访问模板化方法

    Spring数据访问模板化方法

    今天小编就为大家分享一篇关于Spring数据访问模板化,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01

最新评论