zoukankan      html  css  js  c++  java
  • 基础篇-java优势,类初始化,克隆

    1   java与C和C++相比的优势------------------------------begin----------------------------------

     1.1   java纯面向对象,万事万物皆对象

     1.2   平台无关性: 编译器把java代码编译为中间代码(字节码),字节码与平台无关,在java虚拟机(JVM)上即可执行

     1.3  提供了很多内置类库,简化了开发人员的程序设计工作,缩短了项目开发时间:如多线程,网络通信,垃圾回收(GC),最重要的是提供了GC,这是得开发人员从对内存的管理中解脱出来。

     1.4  提供了web应用开发的支持

       Applet,Servlet和JSP可以用来开发web应用程序

      Socket,RMI可以用来开发分布式应用程序的类库

     1.5  具有较好的安全性和健壮性

       java提供了一个防止恶意代码工具的安全机制,强制类型转换,垃圾回收器,异常处理,安全检查机制,使得java程序有很好的健壮性。

     1.6  去除了c++中难以理解,容易混淆的特性,如头文件,指针,结构,单元,运算符重载,多重继承等,使程序根据严谨,简洁。

    2  类初始化顺序-----------------------------begin-------------------------------------

     实例化对象时,对象所在类的所有成员变量首先要进行初始化,初始化完成后,才会调用构造函数创建对象

     原则:1 静态优先   2父类优先于子类 3 按成员变量定义顺序初始化

     顺序:

            父类静态变量>父类静态代码块>子类静态变量>子类静态代码块>父类非静态变量>父类非静态代码块

    >父类构造函数>子类非静态变量>子类非静态代码块>子类构造函数 

    3 克隆对象-------------------------------begin-----------------------------------------

        3.1 目的:

         我们总会需要某个新的对象B,拥有和原对象A一样的状态,但修改新对象B时不改变原对象A的状态。

      我们可以new一个新对象B,然后把原对象A的属性一个个手动赋值给新对象B,但很繁琐。

    所以才有了 克隆   用克隆造出一个对象副本。

       3.2 如何实现:

       方法1 Object 自带浅克隆方法 

    protected native Object clone() throws CloneNotSupportedException;

    说明:1.这是一个navtive方法  2.要使用该方法必须继承Object类,因为修饰符为protected  3.返回值为Object,需要强转

    浅度克隆

    public class Empolyee implements Serializable,Cloneable {
        private static final long serialVersionUID = 199958867467854597L;
        //职位
        private String title;
        //人员
        private Person person;
        /**
         * 克隆方法
         * @return
         */
        @Override
        protected Object clone() {
            Empolyee empolyee = null;
            try {
                empolyee = (Empolyee) super.clone();
                //引用类型
               // empolyee.setPerson((Person)person.clone());
                return empolyee;
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            return null;
        }

    如上图,调用了超类的clone方法

        //克隆测试类
        public void shallowCloneTest() throws Exception {
            //初始化对象
            Empolyee empolyeeOld = new Empolyee();
            Person person = new Person();
            person.setAge("18");
            person.setSex("男");
            person.setName("小铁");
            empolyeeOld.setPerson(person);
            empolyeeOld.setTitle("高中学生");
    
            //克隆对象
            Empolyee employeeNew = (Empolyee)empolyeeOld.clone();
            System.out.println("原对象="+JsonUtils.toJson(empolyeeOld));
            employeeNew.getPerson().setAge("40");
            employeeNew.getPerson().setName("老铁");
            System.out.println("修改新对象 年龄=40,姓名=老铁");
            System.out.println("原对象="+JsonUtils.toJson(empolyeeOld));
            System.out.println("新对象="+JsonUtils.toJson(employeeNew));
        }

    浅克隆测试,输出结果

    原对象={"person":{"age":"18","name":"小铁","sex":"男"},"title":"高中学生"}
    修改新对象 年龄=40,姓名=老铁,职位=上市公司CEO
    原对象={"person":{"age":"40","name":"老铁","sex":"男"},"title":"高中学生"}
    新对象={"person":{"age":"40","name":"老铁","sex":"男"},"title":"上市公司CEO"}

         可以看到改了新对象的Person属性 年龄,姓名  原对象也改了

    改了新对象的职位,原对象职位值未变

    得出结论  Object的clone 方法是浅克隆,只克隆基础数据类型,其中新对象中引用类型和数组都还是指向原对象的引用。

    方法2  用clone做深度克隆

    还是用clone方法,但对复杂类型的属性,单独再克隆一次

        /**
         * 克隆方法
         * @return
         */
        @Override
        public Object clone() {
            Empolyee empolyee = null;
            try {
                empolyee = (Empolyee) super.clone();
                //复杂类型属性克隆
                empolyee.setPerson((Person)person.clone());
                return empolyee;
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            return null;
        }

    继续运行克隆测试类

    测试结果
    原对象={"person":{"age":"18","name":"小铁","sex":"男"},"title":"高中学生"}
    修改新对象 年龄=40,姓名=老铁,职位=上市公司CEO
    原对象={"person":{"age":"18","name":"小铁","sex":"男"},"title":"高中学生"}
    新对象={"person":{"age":"40","name":"老铁","sex":"男"},"title":"上市公司CEO"}

     可以看出,修改了新对象不管是基本数据类型,还是引用类型的值,原对象都不会改变

    可以得出结论,此为深度克隆

    但是这种方式很繁琐,如果有大量复杂类型的成员变量(类属性),那就要分别对各属性克隆。所以我们应该找更好的方法来做 深度克隆。

    方法3  用序列化方式做深度克隆

        /**
         * 深度克隆方法
         *
         * @param needCloneObject 需要克隆对象
         * @return
         */
        public static Object deepClone(Object needCloneObject) throws Exception {
            Object objNewOne = null;
            if (needCloneObject != null) {
                //把对象序列化为字节流
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                ObjectOutputStream oos = new ObjectOutputStream(baos);
                oos.writeObject(needCloneObject);
                oos.close();
    
                //把字节流反序列化为对象
                ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
                ObjectInputStream ois = new ObjectInputStream(bais);
                objNewOne = ois.readObject();
                ois.close();
            }
    
            return objNewOne;
        }

    调用测试方法

        @Test
        public void cloneTest() throws Exception {
            //初始化对象
            Empolyee empolyeeOld = new Empolyee();
            Person person = new Person();
            person.setAge("18");
            person.setSex("男");
            person.setName("小铁");
            empolyeeOld.setPerson(person);
            empolyeeOld.setTitle("高中学生");
    
            //调用序列化深度克隆方法  克隆对象
            Empolyee employeeNew = (Empolyee)deepClone(empolyeeOld);
            System.out.println("原对象="+JsonUtils.toJson(empolyeeOld));
            employeeNew.getPerson().setAge("40");
            employeeNew.getPerson().setName("老铁");
            employeeNew.setTitle("上市公司CEO");
            System.out.println("修改新对象 年龄=40,姓名=老铁,职位=上市公司CEO");
            System.out.println("原对象="+JsonUtils.toJson(empolyeeOld));
            System.out.println("新对象="+JsonUtils.toJson(employeeNew));
        }
    输出结果

    原对象={"person":{"age":"18","name":"小铁","sex":"男"},"title":"高中学生"}
    修改新对象 年龄=40,姓名=老铁,职位=上市公司CEO
    原对象={"person":{"age":"18","name":"小铁","sex":"男"},"title":"高中学生"}
    新对象={"person":{"age":"40","name":"老铁","sex":"男"},"title":"上市公司CEO"}

    可以看出,修改了新对象不管是基本数据类型,还是引用类型的值,原对象都不会改变,为深度克隆

    而且此种方式的性能也做好,所以强烈推荐使用。

    ------------------------------------------克隆 end-----------------------------------------

  • 相关阅读:
    Maidsafe-去中心化互联网白皮书
    The Top 20 Cybersecurity Startups To Watch In 2021 Based On Crunchbase
    Top 10 Blockchain Security and Smart Contract Audit Companies
    The 20 Best Cybersecurity Startups To Watch In 2020
    Blockchain In Cybersecurity: 11 Startups To Watch In 2019
    004-STM32+BC26丨260Y基本控制篇(阿里云物联网平台)-在阿里云物联网平台上一型一密动态注册设备(Android)
    涂鸦开发-单片机+涂鸦模组开发+OTA
    000-ESP32学习开发-ESP32烧录板使用说明
    03-STM32+Air724UG远程升级篇OTA(阿里云物联网平台)-STM32+Air724UG使用阿里云物联网平台OTA远程更新STM32程序
    03-STM32+Air724UG远程升级篇OTA(自建物联网平台)-STM32+Air724UG实现利用http/https远程更新STM32程序(TCP指令,单片机程序检查更新)
  • 原文地址:https://www.cnblogs.com/hup666/p/12019960.html
Copyright © 2011-2022 走看看