• 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("我觉得还可以挽救");
        }

    再进行测试 

    1. package com.openlab.day15;
    2. import org.junit.jupiter.api.Test;
    3. public class TestObject {
    4. @Test
    5. void testFinalize() {
    6. User u = new User();
    7. u = null;
    8. //把u置空,对于gc而言,内存不一定已经变为空了
    9. //java的垃圾回收机制是自动在维护的,不是程序员维护。c立刻回收,java不是
    10. //标记为空相当于告诉垃圾回收机制,这个是垃圾,垃圾回收机制会过来回收,但是
    11. //过来回收的时间不确定,有时候会立刻过来回收,有时候会等一会过来回收
    12. System.gc();//手动调用gc,让立即回收
    13. try {
    14. Thread.sleep(3000);
    15. } catch (InterruptedException e) {
    16. e.printStackTrace();
    17. }
    18. }
    19. }

     

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

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

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

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

     

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

     

     

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

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

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

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

    1.引用传递

    1. package com.openlab.day15;
    2. public class User {
    3. private Integer id;
    4. private String username;
    5. private String password;
    6. private String nickname;
    7. private Integer age;
    8. public Integer getId() {
    9. return id;
    10. }
    11. public void setId(Integer id) {
    12. this.id = id;
    13. }
    14. public String getUsername() {
    15. return username;
    16. }
    17. public void setUsername(String username) {
    18. this.username = username;
    19. }
    20. public String getPassword() {
    21. return password;
    22. }
    23. public void setPassword(String password) {
    24. this.password = password;
    25. }
    26. public String getNickname() {
    27. return nickname;
    28. }
    29. public void setNickname(String nickname) {
    30. this.nickname = nickname;
    31. }
    32. public Integer getAge() {
    33. return age;
    34. }
    35. public void setAge(Integer age) {
    36. this.age = age;
    37. }
    38. public User() {
    39. super();
    40. }
    41. public User(Integer id, String username, String password, String nickname, Integer age) {
    42. super();
    43. this.id = id;
    44. this.username = username;
    45. this.password = password;
    46. this.nickname = nickname;
    47. this.age = age;
    48. }
    49. @Override
    50. public String toString() {
    51. return "User [id=" + id + ", username=" + username + ", password=" + password + ", nickname=" + nickname
    52. + ", age=" + age + "]";
    53. }
    54. }
    1. package com.openlab.day15;
    2. import org.junit.jupiter.api.Test;
    3. public class TestObject {
    4. @Test
    5. void testObjectClone() {
    6. //创建一个对象
    7. User u1 = new User(1, "张三", "123456", "法外狂徒", 20);
    8. System.out.println(u1);
    9. //引用传递
    10. User u2 = u1;//u1存的是内存地址,把u1给u2就是把内存地址给u2
    11. System.out.println(u1 == u2);
    12. }
    13. }

     

     

    如果将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{

    }

    1. package com.openlab.day15;
    2. //在java中,如果需要拷贝对象,一定要去实现Cloneable接口
    3. public class User implements Cloneable{
    4. private Integer id;
    5. private String username;
    6. private String password;
    7. private String nickname;
    8. private Integer age;
    9. public Integer getId() {
    10. return id;
    11. }
    12. public void setId(Integer id) {
    13. this.id = id;
    14. }
    15. public String getUsername() {
    16. return username;
    17. }
    18. public void setUsername(String username) {
    19. this.username = username;
    20. }
    21. public String getPassword() {
    22. return password;
    23. }
    24. public void setPassword(String password) {
    25. this.password = password;
    26. }
    27. public String getNickname() {
    28. return nickname;
    29. }
    30. public void setNickname(String nickname) {
    31. this.nickname = nickname;
    32. }
    33. public Integer getAge() {
    34. return age;
    35. }
    36. public void setAge(Integer age) {
    37. this.age = age;
    38. }
    39. public User() {
    40. super();
    41. }
    42. public User(Integer id, String username, String password, String nickname, Integer age) {
    43. super();
    44. this.id = id;
    45. this.username = username;
    46. this.password = password;
    47. this.nickname = nickname;
    48. this.age = age;
    49. }
    50. @Override
    51. public String toString() {
    52. return "User [id=" + id + ", username=" + username + ", password=" + password + ", nickname=" + nickname
    53. + ", age=" + age + "]";
    54. }
    55. @Override
    56. protected Object clone() throws CloneNotSupportedException {
    57. return super.clone();
    58. }
    59. }

     

    1. package com.openlab.day15;
    2. import org.junit.jupiter.api.Test;
    3. public class TestObject {
    4. @Test
    5. void testObjectClone() {
    6. //创建一个对象
    7. User u1 = new User(1, "张三", "123456", "法外狂徒", 20);
    8. System.out.println(u1);
    9. User u2 = u1;
    10. System.out.println(u1 == u2);
    11. //u1 = null;
    12. //System.out.println(u2);
    13. try {
    14. User u3 = (User) u1.clone();//要做强转(u1.clone()是Object)
    15. System.out.println(u1 == u3);
    16. System.out.println(u2 == u3);
    17. System.out.println(u3);
    18. } catch (CloneNotSupportedException e) {
    19. e.printStackTrace();
    20. }
    21. }
    22. }

     

     

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

    以下介绍浅拷贝。

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

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

    1. package com.openlab.day15;
    2. public class Cat {
    3. private int id;
    4. private String name;
    5. public int getId() {
    6. return id;
    7. }
    8. public void setId(int id) {
    9. this.id = id;
    10. }
    11. public String getName() {
    12. return name;
    13. }
    14. public void setName(String name) {
    15. this.name = name;
    16. }
    17. public Cat() {
    18. super();
    19. }
    20. public Cat(int id, String name) {
    21. super();
    22. this.id = id;
    23. this.name = name;
    24. }
    25. @Override
    26. public String toString() {
    27. return "Cat [id=" + id + ", name=" + name + "]";
    28. }
    29. }
    1. package com.openlab.day15;
    2. import org.junit.jupiter.api.Test;
    3. public class TestObject {
    4. @Test
    5. void testObjectClone() {
    6. //创建一个对象
    7. User u1 = new User(1, "张三", "123456", "法外狂徒", 20);
    8. Cat cat = new Cat(2022, "小贝");
    9. //将小贝交给了主人
    10. u1.setCat(cat);
    11. System.out.println(u1);
    12. User u2 = u1;
    13. System.out.println(u1 == u2);
    14. //u1 = null;
    15. //System.out.println(u2);
    16. try {
    17. User u3 = (User) u1.clone();//要做强转(u1.clone()是Object)
    18. System.out.println(u1 == u3);
    19. System.out.println(u2 == u3);
    20. System.out.println(u3);
    21. System.out.println(u1.getCat() == u3.getCat());
    22. } catch (CloneNotSupportedException e) {
    23. e.printStackTrace();
    24. }
    25. }
    26. }

     

     

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

    对象的深浅拷贝:

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

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

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

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

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

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

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

     

     

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


              
            
        

  • 相关阅读:
    Java 跨域解决
    java 调用 360 接口实现批量查询手机号码归属地
    【论文笔记】Content-based Unrestricted Adversarial Attack
    React中编写操作树形数据的自定义Hook
    MismatchedInlineShardingAlgorithmExpressionAndColumnException
    Scala运算符及流程控制
    okhttp
    React自定义Hook之useRequest
    计算机的硬件(计算机组成原理)
    第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(沈阳),签到题4题
  • 原文地址:https://blog.csdn.net/m0_58679504/article/details/126048580