java编程基础总结——16.Object类

一、Object类:

    Object类是java中所有类父类
    java.lang.Object

 
native关键字
    被它修饰的方法,叫做本地方法
    都是没有实现体。
    JVM在底层使用C/C++实现。

方法:

   1.  public final native Class<?> getClass();    // 获取类的字节码文件
    
   

 

   2. public native int hashCode();            // 获取对象的hashcode(获取对象的内存地址的hashcode值)

        对象都是有内存地址的。如int a = 10,是把10存在一个内存地址。在java中,为了方便,把内存地址做了哈希算法,最终获取一个hashcode值,这个值也是native的,是底层实现的

 

  

    3. public boolean equals(Object obj)            // 比较对象,默认使用== ,比较的是内存地址

         字符串重写了该方法,因为字符串一般比较的是内容,而不是地址


    

 

 4. public String toString()            // 以字符串的形式展示对象信息,打印对象时调用

     返回的是 对象的类名称 + @ + 十六进制数字(内存地址的16进制值)


       getClass()                            拿到字节码文件。getName()获取类的名称

       getClass().getName()          获取类的名称。注意:是获取全路径,包名+类名

       Integer.toHexString()           将int值转换成十六进制的字符串

       hashCode()                          获取内存地址的hashcode值

5. public final native void notify()                  //唤醒当前沉睡的线程
6. public final native void notifyAll()              //唤醒当前所有沉睡的线程
7. public final void wait()                              // 让当前线程进行等待。存在三个重载

8. protected void finalize()                           // 该方法在GC(垃圾回收机制)触发前,会自动触发
                                                                   // 在当前对象被GC前,会自动触发
                                                                   // 适合于做一些垃圾回收前的各种工作、挽救工作

先重写该方法 

@Override
    protected void finalize() throws Throwable {
        System.out.println("我觉得还可以挽救");
    }

再进行测试 

package com.openlab.day15;

import org.junit.jupiter.api.Test;

public class TestObject {
	
	@Test
	void testFinalize() {
		User u = new User();
		u = null;
		//把u置空,对于gc而言,内存不一定已经变为空了
		//java的垃圾回收机制是自动在维护的,不是程序员维护。c立刻回收,java不是
		//标记为空相当于告诉垃圾回收机制,这个是垃圾,垃圾回收机制会过来回收,但是
		//过来回收的时间不确定,有时候会立刻过来回收,有时候会等一会过来回收
		System.gc();//手动调用gc,让立即回收
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

 

面试题,这三种的区别和联系:
    final
    finally
    finalize()    在jdk9之后过时了

final和finally是java的关键字,finalize()是Object类提供一个方法

final关键字修饰变量、方法、类,...

finally是用在try语法块中的,写在finally中的代码是必须要执行的

 

9. protected native Object clone() throws CloneNotSupportedException       //对象拷贝

 

 

二、引用传递和对象拷贝:

    引用传递:将栈引用进行复制,堆中的对象始终是一个

    对象拷贝:堆对象会进行复制。借助clone方法

    在java中,如果需要拷贝对象,一定要去该类实现Cloneable接口

1.引用传递

package com.openlab.day15;

public class User {
	private Integer id;
	private String username;
	private String password;
	private String nickname;
	private Integer age;

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	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;
	}

	public String getNickname() {
		return nickname;
	}

	public void setNickname(String nickname) {
		this.nickname = nickname;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	public User() {
		super();
	}

	public User(Integer id, String username, String password, String nickname, Integer age) {
		super();
		this.id = id;
		this.username = username;
		this.password = password;
		this.nickname = nickname;
		this.age = age;
	}

	@Override
	public String toString() {
		return "User [id=" + id + ", username=" + username + ", password=" + password + ", nickname=" + nickname
				+ ", age=" + age + "]";
	}

}
package com.openlab.day15;

import org.junit.jupiter.api.Test;

public class TestObject {
	
	@Test
	void testObjectClone() {
		//创建一个对象
		User u1 = new User(1, "张三", "123456", "法外狂徒", 20);
		System.out.println(u1);
		//引用传递
		User u2 = u1;//u1存的是内存地址,把u1给u2就是把内存地址给u2
		System.out.println(u1 == u2);
	}
	
}

 

 

如果将u1置为空

u1 = null;
System.out.println(u2);

u2还在,虽然一条线没有了,但是另一条还在。

 要是u1和u2都置空,内存就会被回收(在栈中已经没有引用指向堆了)。当没有人引用的时候,这块内存就会被认为是垃圾。java的GC是自动的,有自己的垃圾回收机制,根据特定的算法去回收。

2. 对象拷贝

可以重写clone(),也可以直接调用,习惯于重写该方法

@Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

在java中,如果需要拷贝对象(clone()),一定要去实现Cloneable接口,如果不实现,默认不能克隆。

public class User implements Cloneable{

}

package com.openlab.day15;

//在java中,如果需要拷贝对象,一定要去实现Cloneable接口
public class User implements Cloneable{
	private Integer id;
	private String username;
	private String password;
	private String nickname;
	private Integer age;

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	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;
	}

	public String getNickname() {
		return nickname;
	}

	public void setNickname(String nickname) {
		this.nickname = nickname;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	public User() {
		super();
	}

	public User(Integer id, String username, String password, String nickname, Integer age) {
		super();
		this.id = id;
		this.username = username;
		this.password = password;
		this.nickname = nickname;
		this.age = age;
	}

	@Override
	public String toString() {
		return "User [id=" + id + ", username=" + username + ", password=" + password + ", nickname=" + nickname
				+ ", age=" + age + "]";
	}

	@Override
	protected Object clone() throws CloneNotSupportedException {
		return super.clone();
	}

}

 

package com.openlab.day15;

import org.junit.jupiter.api.Test;

public class TestObject {
	
	@Test
	void testObjectClone() {
		//创建一个对象
		User u1 = new User(1, "张三", "123456", "法外狂徒", 20);
		System.out.println(u1);
		
		User u2 = u1;
		System.out.println(u1 == u2);
		
		//u1 = null;
		//System.out.println(u2);
		
		try {
			User u3 = (User) u1.clone();//要做强转(u1.clone()是Object)
			System.out.println(u1 == u3);
			System.out.println(u2 == u3);
			System.out.println(u3);
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
	}
	
}

 

 

 我们新克隆一个u3,发现u3和u1、u2都不想等,但是它们的值相等。这个拷贝相当于是把u1复制了一份对象放在堆内存,之后赋给u3的引用,叫对象拷贝。这种拷贝叫浅拷贝。

以下介绍浅拷贝。

我们再创建一个猫类,将猫的一个对象交给主人u1。执行这行代码,发现结果为true

System.out.println(u1.getCat() == u3.getCat());

package com.openlab.day15;

public class Cat {
	private int id;
	private String name;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Cat() {
		super();
	}

	public Cat(int id, String name) {
		super();
		this.id = id;
		this.name = name;
	}

	@Override
	public String toString() {
		return "Cat [id=" + id + ", name=" + name + "]";
	}

}
package com.openlab.day15;

import org.junit.jupiter.api.Test;

public class TestObject {
	
	@Test
	void testObjectClone() {
		//创建一个对象
		User u1 = new User(1, "张三", "123456", "法外狂徒", 20);
		Cat cat = new Cat(2022, "小贝");
		//将小贝交给了主人
		u1.setCat(cat);
		
		System.out.println(u1);
		
		User u2 = u1;
		System.out.println(u1 == u2);
		
		//u1 = null;
		//System.out.println(u2);
		
		try {
			User u3 = (User) u1.clone();//要做强转(u1.clone()是Object)
			System.out.println(u1 == u3);
			System.out.println(u2 == u3);
			System.out.println(u3);
			System.out.println(u1.getCat() == u3.getCat());
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
	}
	
}

 

 

        红色的表示猫对象,u1存了猫的地址,复制时把红色的地址复制了过来 ,所以u3的猫地址和u1相同。

对象的深浅拷贝:

1. 浅拷贝:将对象的第一层完成拷贝,使得两个对象完成了基本的分离
                  有可能还存在着藕断丝连,因为有可能有多层对象,多层对象不会做深层次的拷贝

    优点:内存占有较少
    缺点:如果存在底对象,则子对象没有拷贝,还是指向同一个。

2. 深拷贝:
            将两个对象完成分离,彼此之间将无任何关系。
            递归拷贝

    java实现深拷贝有两种方法:
            1)、所有相关对象都实现浅拷贝。有几个实现几个,该方法用的不多

            2)、通过序列化对象实现深拷贝
                        对象 <==> 字节数据  
                        对象 <==> 字符串数据(如JSON)  

1)、所有相关对象都实现浅拷贝

案例中猫实现Cloneable接口,重写clone()方法,最后再添加

 

 

//需要手动添加
u3.setCat((Cat)(u1.getCat().clone()));


          
        
    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值