`

java 创建一个对象 Cloneable

    博客分类:
  • java
阅读更多

 

               JAVA 创建对象的几种方式:

 

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;


public class Obj {

 public static void main(String[] args)
   throws CloneNotSupportedException,
   ClassNotFoundException,
   IllegalAccessException,
   InstantiationException,
   NoSuchFieldException,
   NoSuchMethodException,
   InvocationTargetException,
   IOException{
  //1.使用new 创建一个对象
  User u1=new User();
  Addr a1=new Addr();
  u1.setAddr(a1);
  u1.setAge(1);
  u1.setName("user1");
  a1.setCod("a1");
  a1.setAddress("海淀");
  
  System.out.println("1.使用new创建一个对象   " + u1.toString());
  System.out.println();
 
  //2.使用clone创建一个对象(深度克隆)
  User u2=(User)u1.clone();
  Addr a2=u2.getAddr();
  a2.setCod("a2");
  u2.setName("user2");
  System.out.println("2.2使用clone创建一个对象   " + u2.toString());
  System.out.println("2.3使用clone创建一个对象  " + u1.toString()); //Addr 对象如果clone
  
  //3.反射:利用java.lang.Class 或者 java.lang.reflect.Constructor.newInstance()
  Class c3=Class.forName("jav.User");
  printClass(c3);
  User u3=(User)c3.newInstance();
  Addr a3=u3.getAddr();
  Field field= c3.getDeclaredField("addr");
  String methodName = "set" + field.getName().substring(0,1).toUpperCase() + field.getName().substring(1);
  System.out.println("methodName = "+ methodName);
  Method m=c3.getMethod(methodName, Addr.class);
  
  a3= new Addr();
  a3.setCod("A33");
  Object o=m.invoke(u3, a3); //o是返回值 , User实例通过依赖注入把一个新的对象注入addr属性中
  System.out.println(u3.getAddr() + u3.getAddr().getCod());
  //System.out.println("a3 = null: "+ (a3==null));//true
  u3.setAddr(new Addr());
  System.out.println("3.反射:利用java.lang.Class创建一个对象 " + u3.toString());
  System.out.println("3.2反射:利用java.lang.Class 使用Method.invoke() 实现注入属性对象");
  
  
  Constructor[] cons= User.class.getDeclaredConstructors();//获取默认构造函数
  User u4=null;
  for(int i=0;i<cons.length;i++){
   Class[] paraC=cons[i].getParameterTypes();
   //System.out.println(paraC.length); //默认构造函数 参数为0
   if(paraC.length==0){//默认构造函数
    //System.out.println(cons[i]);
    u4=(User)cons[i].newInstance();
    System.out.println("u4=" +u4.getName() + "addr ="+u4.getAddr());
    //break;
   }
   else if(paraC.length==3){
    Addr a4=new Addr();
    a4.setCod("A44");
    u4=(User)cons[i].newInstance("abc", 12, a4);
    System.out.println("u4=" +u4.getName()+ " addr="+u4.getAddr());
   }
  }
  
  System.out.println("3.3反射 使用java.lang.reflect.Constructor(构造函数)创建一个对象");
  
  //4.反序列化,java.io.ObjectInputStream.readObject()
//  ObjectOutputStream os=new ObjectOutputStream(new FileOutputStream(new File("c:\\BAK\\test.txt")));
//  os.writeObject(u1);//java.io.NotSerializableException
//  os.close();
  
  ObjectInputStream is=new ObjectInputStream(new FileInputStream(new File("c:\\BAK\\test.txt")));
  User u5= (User)is.readObject();
  is.close();
  
  System.out.println("4.反序列化,java.io.ObjectInputStream.readObject 创建一个对象   "+u5);
 }
 
 
 static void printClass(Class c)
   throws IllegalAccessException,
   InstantiationException{
  StringBuffer sb=new StringBuffer(256);
  
  sb.append("name = ")
  .append(c.getName())
  .append("\n")
  .append("simpleName = ")
  .append(c.getSimpleName())
  .append("\n")
  .append("classLoader = ")
  .append(c.getClassLoader())
  .append("\n")
  .append("fields = ");
  
  Field[] fields=c.getDeclaredFields();
  for(int i=0;i<fields.length;i++){
   sb.append(fields[i].getName())
   .append(" ")
   .append(fields[i].getGenericType())
   .append("  ");
   
   //处理addr=null
//   if("class jav.Addr".equals(fields[i].getGenericType())){
//    System.out.println(1000);
//   }
   
   Class c6= fields[i].getType();
   
   if("Addr".equals(c6.getSimpleName())){
    Addr aa=(Addr)c6.newInstance();
   }
  }
  sb.append("\n");
  
  Method[] methods=c.getMethods();
  sb.append("method = ");
  for(int i=0;i<methods.length;i++){
   sb.append(methods[i].getName());
   sb.append(" ");
   
   //method
   //methods[i].invoke(obj, args)
  }
  sb.append("\n");
  
  sb.append("Constructors = ");
  Constructor[] cons=c.getDeclaredConstructors();
  for(int i=0;i<cons.length;i++){
   sb.append(cons[i].getName());
  }
  System.out.println(sb.toString());
 }

}


class User implements Cloneable,Serializable{
 private String name;
 private int age;
 private Addr addr; //Addr 实现Cloneable 深度克隆
 
 public User(){
  
 }
 
 public User(String name,int age, Addr addr){
  this.name=name;
  this.age=age;
  this.addr=addr;
 }
 
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public int getAge() {
  return age;
 }
 public void setAge(int age) {
  this.age = age;
 }
 public Addr getAddr() {
  return addr;
 }
 public void setAddr(final Addr addr) {
  //addr=new Addr();
  this.addr = addr;
 }
 
 public String toString() {
  StringBuilder sb=new StringBuilder();
  sb.ensureCapacity(256);
  sb.append("name: ")
  .append(this.getName())
  .append(" ")
  .append("age: ")
  .append(this.getAge())
  .append(" ")
  .append("addr: ")
  .append(this.getAddr().getCod())
  .append(" ")
  .append(this.getAddr().getAddress());
  
  return sb.toString();
 }

 protected Object clone() throws CloneNotSupportedException {
  User u=(User)super.clone();
  
  //克隆Addr
  u.addr=(Addr)addr.clone();
  return u;
 }
 
 
}

class Addr implements Cloneable,Serializable{
 private String cod;
 private String address;
 
 public String getCod() {
  return cod;
 }
 public void setCod(String cod) {
  this.cod = cod;
 }
 public String getAddress() {
  return address;
 }
 public void setAddress(String address) {
  this.address = address;
 }

 protected Object clone() throws CloneNotSupportedException {
  Addr a=(Addr)super.clone();
  return a;
 }
 
 
}

分享到:
评论

相关推荐

    Java2游戏编程.pdf

    中文名: Java2游戏编程 ...附录C 使用JNI创建一个gamepad阅读器 附录D 使用.JAR文件来部署Java applet 附录E 正确运行Java 2 applet 附录F Magic游戏引擎源码清单 附录G 更多的资源 附录H 配书光盘中有些什么

    新手入门写Java程序的三十个基本规则

    新手入门写Java程序的三十个...(2) 为了常规用途而创建一个类时,请采取“经典形式”,并包含对下述元素的定义:  equals()  hashCode()  toString()  clone()(implement Cloneable)  implement Serializable

    java初学者必看

    2.4 第一个应用程序 2.4.1 HelloWorld程序 2.4.2 程序运行编译命令 2.4.3 HelloWorld编译与运行 2.5 简单开发工具介绍 2.5.1 EditPlus的编译与运行 2.5.2 在UltraEdit上开发Java 2.6 集成开发环境Eclipse介绍 ...

    JAVA高级程序设计测试题含答案.docx

    每一个Java线程可以看成由代码、一个真实的CPU以及数据三部分组成 B. 创建线程的两种方法中,从Thread类中继承的创建方式可以防止出现多父类问题 C. Thread类属于java.util程序包 D. 以上说法无一正确(正确答案) ...

    java编程常见问题

    当可用内存不足以让Java虚拟机分配给一个对象时抛出该错误。 34.java.lang.StackOverflowError 堆栈溢出错误。当一个应用递归调用的层次太深而导致堆栈溢出时抛出该错误。 35.java.lang.ThreadDeath 线程结束。当...

    java编程基础,应用与实例

    1.5 运行第一个Java程序 7 1.6 巩固练习 8 第2章 理解对象与类 9 2.1 什么是对象 9 2.2 什么是类 9 2.3 HelloJava示例的分析 11 2.4 巩固练习 12 第3章 Java语言的基本语法 13 3.1 代码编写规则...

    Java高级程序设计测试含答案.docx

    非流类(正确答案) java中用于创建文件对象的类是() [单选题] * A.File(正确答案) B.Object C.Thread D.Frame 若要将一个类对象能被整体写入文件,则定义该类时必须实现下列哪个接口() [单选题] * A....

    二十三种设计模式【PDF版】

    用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。 B. 结构模式 设计模式之 Adapter(适配器) 使用类再生的两个方式:组合(new)和继承(extends),这个已经在 thinking in java中提到过. 设计模式...

    bigcoder84#study-notes#_4Object中的clone方法1

    Object类中的clone方法clone()方法的作用克隆方法用于创建对象的拷贝,为了使用clone方法,类必须实现java.lang.Cloneable接口

    leetcode分类-DesignPatternAndAlgorithm:常用设计模式和算法,练习用

    leetcode 分类 DesignPatternAndAlgorithm 常用设计模式和算法,练习用。...原型模式:与new一个新对象不同,原型模式是clone出一个新对象。已与java融为一体,实现Cloneable接口。分为深拷贝和浅拷贝。 抽

Global site tag (gtag.js) - Google Analytics