注解与对象克隆

发布时间:2024年01月21日

目录

一、注解

一、什么是注解

二、内置注解

三、元注解

重点掌握

二、对象克隆

一、为什么要克隆

误区:

二、如何实现克隆

三、浅克隆和深克隆

1、浅克隆

2、深克隆

四、解决多层克隆问题


一、注解

一、什么是注解

????????Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。 Java 语言中的类、方法、变量、参数和包等都可以被标注,然后让编译器或运行时其他类解析完成某个功能,注解也可以编译到字节码文件中。

二、内置注解

Java中已经定义好的注解。

@Override - 检查该方法是否是重写方法。如果发现其父类,或者是引用的接 口中并没有该方法时,会报编译错误。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? @Deprecated - 标记过时方法。如果使用该方法,会报编译警告。? ? ? ? ? ? ? ? ? ? ? ? @SuppressWarnings - 指示编译器去忽略注解中声明的警告。? ? ? ? ? ? ? ? ? ? ? ? ? ? @FunctionalInterface 用于指示被修饰的接口是函数式接口。

三、元注解

用于修饰注解的注解,通常用在注解的定义上。

@Retention - 标识这个注解怎么保存,是只在代码中,还是编入 class 文件中, 或者是在运行时可以通过反射访问。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @Documented - 标记这些注解是否包含在用户文档中。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @Target - 标记这个注解应该是哪种 Java 成员。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?@Inherited - 标记这个注解是继承于哪个注解类(默认注解并没有继承于任何 子类)? ? @Repeatable - 标识某注解可以在同一个声明上使用多次。

重点掌握

@Target:注解范围可以用在那些元素上。

ElementType.TYPE 可以应用于类的任何元素。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ElementType.CONSTRUCTOR 可以应用于构造函数。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ElementType.FIELD 可以应用于字段或属性。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ElementType.LOCAL_VARIABLE 可以应用于局部变量。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ElementType.METHOD 可以应用于方法级注释。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ElementType.PACKAGE 可以应用于包声明。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ElementType.PARAMETER 可以应用于方法的参数。

@Retention:注解生效范围。

1.SOURCE:在源文件中有效(即源文件保留)? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 2.CLASS:在 class 文件中有效(即 class 保留)? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 3.RUNTIME:在运行时有效(即运行时保留)

二、对象克隆

一、为什么要克隆

需要一个新的对象来保存当前对象的“状态”要靠 clone 方法。

误区:

? ? ? ? 例如:以下方法是引用,stu1和stu2都是指向同一个地址,同一个对象。

Student stu1 = new Student ();? ? ? ? 
Student stu2 = stu1 ;

二、如何实现克隆

????????基本类型的值可以直接复制,引用类型只能复制引用地址。(引用类型包括 类、接口、数组等复杂类型)

例如:

Person p1 = new Person(100,"jim");
Person p2 =p1.clone();//clone方法 返回一个新对象

三、浅克隆和深克隆

1、浅克隆

????????克隆一个对象时,如果对象中有关联的对象,只将关联对象的地址复制过来。

实现方式:Java 语言中,通过覆盖 Object 类的 clone()方法;

???????????????????spring 框架中提供, BeanUtils.copyProperties(source,target)。

2、深克隆

????????克隆一个对象时,如果对象中有关联的对象,如果将关联的对象也一同克隆(创建一个新的)。

实现方式:在每一层类中都重写clone方法,类实现 Cloneable接口, 但层级多了就比较麻烦。

四、解决多层克隆问题

????????通过序列化(Serialization)实现 Serializable 接口方式来实现。

????????序列化就是将对象写到流的过程,写到流中的对象是原有对象的一个拷贝,而原 对象仍然存在于内存中。通过序列化实现的拷贝不仅可以复制对象本身,而且可 以复制其引用的成员对象,因此通过序列化将对象写到一个流中,再从流里将其 读出来,可以实现深克隆。

例如:


public class Person implements Serializable {//实现Serializable接口

     int num;
     String name;
     Address address;

    public Person() {
    }

    public Person(int num, String name) {
        this.num = num;
        this.name = name;
    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

    public String getName() {
        return name;
    }

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

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    /**
     * 自定义克隆方法
     * @return
     */
    public Person myclone() {
            Person person = null;
              try { // 将该对象序列化成流,因为写在流里的是对象的一个拷贝,而原对象仍然存在于JVM里面。所以利用这个特性可以实现对象的深拷贝
                     ByteArrayOutputStream baos = new ByteArrayOutputStream();
                      ObjectOutputStream oos = new ObjectOutputStream(baos);
                      oos.writeObject(this);
            // 将流序列化成对象
                    ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
                     ObjectInputStream ois = new ObjectInputStream(bais);
                     person = (Person) ois.readObject();
                  } catch (IOException e) {
                     e.printStackTrace();
                  } catch (ClassNotFoundException e) {
                     e.printStackTrace();
                 }
             return person;
          }


    @Override
    public String toString() {
        return "Person{" +
                "num=" + num +
                ", name='" + name + '\'' +
                ", address=" + address +
                '}';
    }
}

文章来源:https://blog.csdn.net/m0_61976036/article/details/135716016
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。