创建对象的几种方式

1,new

Student s = new Student();

在堆储存区开辟了一块空间,其对象的引用存储在栈存储区上。

2,反射 reflect

java的反射机制是指,在运行状态中,对于任意一个类,我们可以获取这个类的属性和方法,对于任意一个对象,我们可以调用这个对象的方法和属性。这种动态获取信息和动态调用对象的方法就是java 的反射机制。

Class 类,每个class 都会有一个Class对象,当我们完成一个类通过编译之后,就会生成一个.class 文件,在生成的.class 文件中,就会有个Class 对象,用于表示这个类的类型信息。

获得类的Class 对象的3中方法:

1,类名.class (任意数据类型,都会有一个class 属性)

2,Class.forName("java.lang.String"); 类的全路径

3,类的实例化对象下,有getClass() 方法。

反射创建对象:

 不存在有参的构造函数:

 方法1:

  类名.class.newInstance(); 就算没有构造方法,也会调用默认的无参构造方法

  Demo newInstance = Demo.class.newInstance();
  newInstance.setUserName("chris");
  newInstance.setPassword("12345");
  System.out.println(newInstance.getUserName()+ newInstance.getPassword());

方法2: 

  和方法1本质相同,一个是使用类名.class ,一个是使用Class.forName("类的全路劲")来获取类的类对象,再通过newInstance()方法创建对象。

  Class<Demo> clazz = (Class<Demo>) Class.forName("Demo");
  Demo newInstance2 = clazz.newInstance();
  newInstance2.setPassword("12345");
  newInstance2.setUserName("Sarah");
  System.out.println(newInstance2.getUserName()+ newInstance2.getPassword());

 

  存在有参的构造函数:

  先获取类的Class 对象,通过类对象获取到指定的构造器,可以是有参,可以是无参,通过指定的构造器,创建对象

  Class<Demo> clazz3 = (Class<Demo>) Class.forName("Demo");
  Constructor<Demo> con = clazz3.getDeclaredConstructor(String.class,String.class);
  Demo newInstance3 = con.newInstance("Mike","12345");
  //newInstance3.setUserName("vincent");可以通过反射是可以改变对象的值
  //newInstance3.setPassword("12345");
  System.out.println(newInstance3.getUserName()+ newInstance3.getPassword());

Class对象获取构造器比较:

Constructor<Demo> con = clazz3.getDeclaredConstructor(String.class,String.class); //能获取到指定参数的构造器,和访问修饰符无关,private,public 所有的可以获取到

Constructor<?>[] conn = clazz4.getConstructors();//所有public 修饰的构造器

Constructor<Demo> connn = clazz5.getConstructor(String.class,String.class);//所有public 修饰的带参数的指定构造器

反射的应用场景:

jdbc的连接

Class.forName("com.mysql.jdbc.Driver")

springIOC反射创建对象

mybatis

3,clone

调用clone,jvm就会创建一个新的对象,将前面对象的内容全部拷贝进去。用clone方法创建对象并不会调用任何构造函数。

前提,必须要实现Cloneable 接口,本地实现 protected native Object clone() throws CloneNotSupportedException;

Demo clone = (Demo) newInstance.clone();

4,反序列化

序列化:将堆内存中的java 对象通过某种方式,存储到磁盘上或者传输给其他网络节点,也就是java对象转成二进制。

反序列化:与序列化相反,再将序列化之后的二进制串再转成数据结构或对象。

为什么需要做序列化?

1,网络节点的传输,java 对象需要转成二进制串。

2,服务器钝化:如果在内存中,一个对象长时间没有被调用,就会将其序列化存储在本地磁盘上,有需要活动的时候,就会现在内存中寻找,找不到,会将磁盘上的二进制再次反序列化成java 对象。可以节省服务器内存。

实现序列化?

1,需要做序列化的对象的类,必须实现序列化接口:Java.lang.Serializable 接口

通过反序列化创建对象。

//本地创建a.txt 文件,并且把对象序列化转成二进制写进文件中

  

  File f = new File(String path)

  OutputStream op = new FileOutputStream(file);  

  ObjectOutputStream ops = new ObjectOutputStream(op);

  ops.writeObject(new Demo("Chris", "12345"));

   ops.close();

//从写进的文件中,读取二进制串,用对象流将其读出

  InputStream in = new FileInputStream(file);

  ObjectInputStream os = new ObjectInputStream(in);

  Demo d = (Demo) os.readObject();

  System.out.println(d.getUserName()+ d.getPassword());

   os.close();

反序列化 请注意深复制和浅复制

https://www.cnblogs.com/pickKnow/p/11104193.html

原文地址:https://www.cnblogs.com/pickKnow/p/9517687.html