欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中clone方法使用筆記

 更新時間:2023年02月10日 10:23:33   作者:吃橘子的Crow  
clone顧名思義是復(fù)制,在Java語言中,clone方法被對象調(diào)用,所以會復(fù)制對象,下面這篇文章主要給大家介紹了關(guān)于Java中clone方法使用的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下

注解

定義: 注解是一種注釋機制,它可以注釋包、類、方法、變量、參數(shù),在編譯器生成類文件時,標(biāo)注可以被嵌入到字節(jié)碼中。

注解的分類:

內(nèi)置注解

Override :重寫方法,引用時沒有該方法時會編譯錯誤

public class Animals {
    public void run(){
        System.out.println("動物跑");
    }
}
public class Cat extends Animals{
    @Override
    public void run1() {
        super.run();
    }
}

Deprecated :標(biāo)記過時方法,會造成編譯警告

public class Animals {
    @Deprecated
    public void run(){
        System.out.println("動物跑");
    }
}

SuppressWarnings :用于編譯器去忽略注解中的聲明報告

FunctionalInterface :用于指示被修飾的接口是函數(shù)式接口

元注解(修飾注解的注解)

@Retention -標(biāo)記這個注解存儲在哪里

@Documented -標(biāo)記這些注解是否包含在用戶文檔中

@Target -標(biāo)記這些注解時java哪種成員

public enum ElementType {
    /** Class, interface (including annotation type), or enum declaration */
    //可以應(yīng)用于類的任何元素
    TYPE,
 
    //可以用于字段或?qū)傩?
    /** Field declaration (includes enum constants) */
    FIELD,
 
    //可以用于方法級注釋
    /** Method declaration */
    METHOD,
 
    //可以用于方法的參數(shù)
    /** Formal parameter declaration */
    PARAMETER,
 
    //可以應(yīng)用于構(gòu)造函數(shù)
    /** Constructor declaration */
    CONSTRUCTOR,
 
    //可以用于局部變量
    /** Local variable declaration */
    LOCAL_VARIABLE,
 
    /** Annotation type declaration */
    ANNOTATION_TYPE,
 
    //可以用于包聲明
    /** Package declaration */
    PACKAGE,
 
    /**
     * Type parameter declaration
     *
     * @since 1.8
     */
    TYPE_PARAMETER,
 
    /**
     * Use of a type
     *
     * @since 1.8
     */
    TYPE_USE
}

@Inherited -標(biāo)記這個注解時繼承于哪個類

@Repeatable -標(biāo)識某注解可以在同一個聲明上使用多次

public enum RetentionPolicy {
    /**
     * Annotations are to be discarded by the compiler.
     */
    SOURCE,//在源文件中有效(源文件保存)
 
    /**
     * Annotations are to be recorded in the class file by the compiler
     * but need not be retained by the VM at run time.  This is the default
     * behavior.
     */
    CLASS,//在class文件中有效(class保存)
 
    /**
     * Annotations are to be recorded in the class file by the compiler and
     * retained by the VM at run time, so they may be read reflectively.
     *
     * @see java.lang.reflect.AnnotatedElement
     */
    RUNTIME//在運行時有效(運行時保留)
}

自定義注解

注解類:

@Target(ElementType.FIELD)//作用在類的屬性上
@Retention(RetentionPolicy.RUNTIME)//運行時生效
public @interface NotNull {
 
    String message() default "";
    
    int length() default 0;
    
    String lengthmessage() default "";
}

model類:

public class User {
    
    private int num;
 
    @NotNull(message="姓名不能為空",length=3,lengthmessage="長度不能小于3")
    private String name;
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public int getNum() {
        return num;
    }
 
    public void setNum(int num) {
        this.num = num;
    }
 
}

測試代碼:

public class Test {
 
      public static void main(String[] args) throws NoSuchMethodException, SecurityException, Exception {
            User user=new User();
          Field[] fields=user.getClass().getDeclaredFields();//將類中的字段存儲在field數(shù)組中
          //對數(shù)組中的字段進行強循環(huán)
          for(Field filed:fields){
              NotNull notNull=filed.getAnnotation(NotNull.class);//獲取注釋類型
              if(notNull!=null){
    Method method = user.getClass().getMethod("get" + getMethodName(filed.getName()));//獲取方法對象
           Object value = method.invoke(user);//調(diào)用類的實例對象
             if(value==null){
           System.err.println(filed.getName()+notNull.message());//打印輸出相應(yīng)的字段和注釋信息
                      throw new NullPointerException(notNull.message());//拋出異常信息
                  }
                  else if(String.valueOf(value).length()< notNull.length()){//判斷字符串長度
                      System.err.println(filed.getName()+notNull.lengthmessage());
 
                  }
              }
          }
 
       }
 
        /**
         * 把一個字符串的第一個字母大寫
         */
        private static String getMethodName(String fildeName) throws Exception {
            byte[] items = fildeName.getBytes();
            items[0] = (byte) ((char) items[0] - 'a' + 'A');
            return new String(items);
        }
}

對象克隆

原因:new出來的對象屬性都是初始化的值,不能保存當(dāng)前對象“狀態(tài)”,clone解決了這個問題

//這種形式的代碼復(fù)制的是引用,即對象在內(nèi)存中的地址,car1和car2指向同一個對象
Car car1=new Car();
Car car2=car1;

如何實現(xiàn)克隆

克隆分為淺克隆和深克隆,下面就簡單的介紹它們之前的區(qū)別:

  • 淺克隆(值類型克隆值,引用類型傳遞地址)

model類:

public class Person implements  Cloneable{
 
     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;
    }
 
    @Override
    protected Person clone() throws CloneNotSupportedException {
        Person person = (Person)super.clone();
       // person.address = (Address)address.clone();   //深度復(fù)制  聯(lián)同person中關(guān)聯(lián)的對象也一同克隆.
        return person;
    }
    @Override
    public String toString() {
        return "Person{" +
                "num=" + num +
                ", name='" + name + '\'' +
                ", address=" + address +
                '}';
    }
}

引用類:

public class Address {
 
     String  address;
 
    public String getAddress() {
        return address;
    }
 
    public void setAddress(String address) {
        this.address = address;
    }
 
    @Override
    public String toString() {
        return "Address{" +
                "address='" + address + '\'' +
                '}';
    }
 
    @Override
    protected Address clone() throws CloneNotSupportedException {
        return (Address)super.clone();
    }
}

測試類:

public class Test {
 
    public static void main(String[] args) throws CloneNotSupportedException {
 
        Address address = new Address();
                address.setAddress("漢中");
 
        Person p1 = new  Person(100,"jim");
               p1.setAddress(address);
 
        Person p2 =p1.clone();
               p2.setName("tom");
               address.setAddress("西安");//
        System.out.println(p1);
    }
}

淺克隆中引用對象進行的是引用地址傳遞,原引用對象和克隆對象指向同一個引用地址

強克?。ㄖ殿愋涂寺≈?,引用類型克隆一個帶有原數(shù)據(jù)的新的地址)

引用類:

public class Address implements Cloneable{
 
     String  address;
 
    public String getAddress() {
        return address;
    }
 
    public void setAddress(String address) {
        this.address = address;
    }
 
    @Override
    public String toString() {
        return "Address{" +
                "address='" + address + '\'' +
                '}';
    }
 
    @Override
    protected Address clone() throws CloneNotSupportedException {
        return (Address)super.clone();
    }
}

model類:

public class Person implements  Cloneable{
 
     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;
    }
 
    @Override
    protected Person clone() throws CloneNotSupportedException {
        Person person = (Person)super.clone();
        person.address = (Address)address.clone();   //深度復(fù)制  聯(lián)同person中關(guān)聯(lián)的對象也一同克隆.
        return person;
    }
 
    @Override
    public String toString() {
        return "Person{" +
                "num=" + num +
                ", name='" + name + '\'' +
                ", address=" + address +
                '}';
    }
}

測試:

public class Test {
 
    public static void main(String[] args) throws CloneNotSupportedException {
 
        Address address = new Address();
                address.setAddress("漢中");
 
        Person p1 = new  Person(100,"jim");
               p1.setAddress(address);
 
        Person p2 =p1.clone();
               p2.setName("tom");
               address.setAddress("西安");
        System.out.println(p1);
        System.out.println(p2);
    }
}

強克隆中的引用類型新創(chuàng)建的地址賦給克隆對象引用類型

我們也可以通過序列化的方式對對象進行克隆,代碼如下:

引用類:

public class Address  implements Serializable {
 
     String  address;
 
    public String getAddress() {
        return address;
    }
 
    public void setAddress(String address) {
        this.address = address;
    }
 
    @Override
    public String toString() {
        return "Address{" +
                "address='" + address + '\'' +
                '}';
    }
 
}

model類:

 
public class Person implements 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里面。所以利用這個特性可以實現(xiàn)對象的深拷貝
                     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 +
                '}';
    }
}

測試類:

public class Test {
 
    public static void main(String[] args) throws CloneNotSupportedException {
 
        Address address = new Address();
                address.setAddress("漢中");
 
        Person p1 = new  Person(100,"jim");
        p1.setAddress(address);
 
        Person p2 =p1.myclone();
               p2.setName("tom");
               address.setAddress("西安");
 
        System.out.println(p1);
        System.out.println(p2);
 
 
    }
}

總結(jié)

到此這篇關(guān)于Java中clone方法使用的文章就介紹到這了,更多相關(guān)Java中clone方法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論