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

  • 相关阅读:
    查看执行SQL效果,消耗资源的SQL查看命令
    网页上搜索apk链接工具
    PL/SQL 获取一个月的天数排除周六周日
    java 数字转换
    jQuery选择器
    Oracle 10g 透明网关 sql server2005 配置
    怎么进行软件测试才能把bug降到最低呢??
    Demon推荐的Blog和网站
    基于.NET的俄罗斯方块课程设计
    【读书笔记】《锋利jQuery》第一章
  • 原文地址:https://www.cnblogs.com/hup666/p/12019960.html
Copyright © 2011-2022 走看看