• JAVA创建对象的五种方式


    最近在学习JAVA知识,通过网上翻看资料,发现原先有的理解不深的东西,渐渐明白了些。对象的使用,在编写软件过程中是必不可少的,不知道大家有没和我一样,几乎都是使用new来创建。那么,问题来了,JAVA有几种创建对象 的方式呢?

    • 使用new关键字创建。
    • 使用Class的newInstance()方法, 位于java.lang包,比如Person类,创建对象可以使用,但是下面的两种方式不能调用private构造函数,且构造对象的类中必须包含无参构造函数(构造器需可见 visible),否则会报错,对于捕获或者未捕获的异常均由构造器抛出;。
      public class person  {
          /**
           * 
           */
          private static final long serialVersionUID = 10L;
          String name = "Jack";
          public person(){
              this.name = name + " ma";
              System.out.println("construct Person");
          }
          
          private person(int a,int b) {
              System.out.println("a:"+a+ " b:" + b);
          }
          @Override
          public String toString() {
              return name;
          }
          
          
      }
      
      方法一
      //这里的testReflect为包名,Person类在此包下
      Class clazz = Class.forName("testReflect.person ");
      person p = (person ) clazz.newInstance();
      
      
      方法二
      person p =person .class.newInstance();
    • 使用Constructor类的newInstance方法,此方法属于反射,位于 java.lang.reflect 包,可以调用任何作用域的构造函数,private也可以,且创建对象的类构造函数可以任意。
      //调用无参构造函数 ,方式一
      person p = person.class.getDeclaredConstructor().newInstance();
      //调用无参构造函数 ,方式二
      Constructor c1=person.class.getDeclaredConstructor();
      c1.setAccessible(true);
      person p=(person)c1.newInstance();  

      这里大家思考下,在调用无参构造函数时,方式一和方式二有什么区别? 大家应该看到了c1.setAccessible(true); 这句代码吧,查看方法的定义包含如下:A value of true indicates that the reflected object should suppress Java language access checking when it is used,意思是为true的时候禁止验证授权,换句话的理解就是,private的无参构造也可以调用。这就是方式一和方式二的区别,方式一若private作用域修饰,则会报错。通常会把抛出的异常封装成InvocationTargetException抛出。

             因为以上差异,所以很多框架使用的都是构造器反射的方式获取对象,像Spring, Guava, Zookeeper, Jackson, Servlet 等。

    • //调用有参构造函数
      Constructor c1=person.class.getDeclaredConstructor(new Class[] {int.class,int.class});
      或
      Constructor  c1=person.class.getDeclaredConstructor(int.class,int.class);
      • public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
                                              throws NoSuchMethodException,
                                                     SecurityException
        • Parameters:
          parameterTypes - the parameter array
          Returns:
          The Constructor object for the constructor with the specified parameter list 
          传入参数为数组。
    • 使用Clone的方法:无论何时我们调用一个对象的clone方法,JVM就会创建一个新的对象,将前面的对象的内容全部拷贝进去,用clone方法创建对象并不会调用任何构造函数。要使用clone方法,创建对象的类必须实现Cloneable接口并实现其定义的clone方法。关于clone可参考我转载的JAVA深复制与浅复制
    • 使用反序列化:当我们序列化和反序列化一个对象,JVM会给我们创建一个单独的对象,在反序列化时,JVM创建对象并不会调用任何构造函数。为了反序列化一个对象,对应类需实现Serializable接口,附上一段具体实现代码。
      import java.io.FileInputStream;
      import java.io.FileOutputStream;
      import java.io.ObjectInputStream;
      import java.io.ObjectOutputStream;
      import java.io.Serializable;
      public class People implements Serializable{
          private String name;
          public People(){
              this.name = "6点A君";
              System.out.println("construct people");
          }
          @Override
          public String toString() {
              return this.name;
          }
          
          public static void main(String[] args) {
              People p = new People();
              System.out.println(p);
              ObjectOutputStream oos = null;
              ObjectInputStream ois = null;
              try {
                  FileOutputStream fos = new FileOutputStream("test.out");
                  oos = new ObjectOutputStream(fos);
                  oos.writeObject(p);
                  oos.close();
              } catch (Exception e) {
                  e.printStackTrace();
              }
              People p1;
              try {
                  FileInputStream fis = new FileInputStream("test.out");
                  ois = new ObjectInputStream(fis);
                  p1 = (People)ois.readObject();
                  System.out.println(p1);
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
      }
  • 相关阅读:
    HTTP 协议(一)之基本概念入门
    聊聊 PHP 私有组件以及如何创建自己的 PHP 组件 (转)
    组件、框架、Packagist、Composer
    laravel 资源篇
    190318 面试题记录
    Http 协议
    python中全局变量的修改
    python lamba表达式
    python 按位置关系输出矩阵元素
    python 三目运算
  • 原文地址:https://www.cnblogs.com/gudaozi/p/8353600.html
Copyright © 2020-2023  润新知