• 对象的创建与克隆


    • 显示创建对象
    package com.xing.test;
    
    public class Name implements Cloneable{
    
        /**
         * @param args
         * 创建对象与对象克隆
         */
        private String name;
        private int age;
        public Name(){
            
        }
        public Name(String name, int age) {
            this.name=name;
            this.age=age;
        }
        public String toString(){
            return "学生姓名:"+name+",学生年龄:"+age;
        }
        public static void main(String[] args) throws Exception {
            System.out.println("----------new-------------");
            Name pp=new Name("小二",55);
            System.out.println(pp);
            System.out.println("----------调用对象的clone()方法创建对象-------------");
            Name pp3=(Name)pp.clone();
            System.out.println(pp3);
            System.out.println("----------调用java.lang.Class的newInstance()方法创建对象-------------");        
            Class qq=Class.forName("com.xing.test.Name");
            Name pp2=(Name) qq.newInstance();
            System.out.println(pp2);
            
        }
    
    }

    注:

    使用new和java.lang.Class的newInstance()方法创建对象时,都会调用类的构造方法。后者会调用类的默认构造方法即无参构造方法,如果新建的构造方法覆盖了原来的构造方法,必须在重新写一个无参构造。使用object类的clone()方法创建对象时,不会调用类的构造方法,他会创建一个复制的对象,这个对象和原来的对象具有不同的内存地址,但他们的属性值相同。

    • 隐含创建对象

    1、String name="hah";"hah"就是一个String对象由java虚拟机隐含的创建。

    2、字符串的+运算符的结果为一个新的String对象

    string a1="a";

    string a2="b";

    string a3=a1+a2;这时a3就是一个新的String对象

    3、当Java虚拟机加载一个类时,会隐含的创建描述这个类的class实例

    类的加载是指把类的.class文件中的二进制数据读入到内存中,把他存放在运行时数据区的方法去内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构。

    • 如何实现对象克隆
    • 有两种方式:
        1). 实现Cloneable接口并重写Object类中的clone()方法;
        2). 实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆,代码如下。
    package com.xing.test;
    
    public class Clonetest {
         public static void main(String[] args) {
                try {
                    Person1 p1 = new Person1("Hao LUO", 33, new Car("Benz", 300));
                    Person1 p2 = Myutil.clone(p1);   // 深度克隆
                    p2.getCar().setBrand("BYD");
                    // 修改克隆的Person对象p2关联的汽车对象的品牌属性
                    // 原来的Person对象p1关联的汽车不会受到任何影响
                    // 因为在克隆Person对象时其关联的汽车对象也被克隆了
                    System.out.println(p1);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
    }

     基于序列化和反序列化实现的克隆不仅仅是深度克隆,更重要的是通过泛型限定,可以检查出要克隆的对象是否支持序列化,这项检查是编译器完成的,不是在运行时抛出异常,这种是方案明显优于使用Object类的clone方法克隆对象。让问题在编译的时候暴露出来总是优于把问题留到运行时。

    序列化总结:

    a)当一个父类实现序列化,子类自动实现序列化,不需要显式实现Serializable接口;

    b)当一个对象的实例变量引用其他对象,序列化该对象时也把引用对象进行序列化;

    c) static,transient后的变量不能被序列化;

  • 相关阅读:
    linux 操作 I/O 端口
    linux I/O 端口分配
    大数问题:求n的阶乘
    POJ 2586 Y2K Accounting Bug
    每天一点儿Java--ComboBox
    android的一些控件
    解决Linux(ubuntu),windows双系统重装后恢复开机选单
    Mysql数据备份与恢复
    log4net 存储到oracle 调试 Could not load type [log4net.Appender.OracleAppender]
    POJ 2533 Longest Ordered Subsequence
  • 原文地址:https://www.cnblogs.com/tjlgdx/p/6138787.html
Copyright © 2020-2023  润新知