问题:实例化对象时一定要用new调用构造方法吗?
 答案:用普通的创建方法(new)是要调用构造方法,如果使用反射或者克隆这些就可以绕过构造函数直接创建对象
 实例:
/*  * ClassTest.java -- JDK 1.8  */ package T20190328;  import java.io.File; import java.io.IOException; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.List;  import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException;  import org.junit.Test; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException;  /**  * Description:  * <p>  * 通过反射访问私有构造方法 例如:  *   * <pre>  * <code>  * // 1.获取类A中声明的构造器  * Class clazz = Class.forName("T20190328.A");  * Constructor constructor = clazz.getDeclaredConstructor(); // 假设A中只有一个私有构造方法  * // 2.设置私有访问权限  * constructor.setAccessible(true);   * constructor.newInstance();  * </code>  * </pre>  * <p>  * @author shuvidora  * @date 2019-03-28 Thu PM 14:22:07  */  public class ClassTest {      static List<A> list = new ArrayList<A>();      @SuppressWarnings("unchecked")     public static <T> T[] cast(Object[] obj) {         return (T[]) obj;     }      public static void showTypes(Type[] arr) {         int len = arr.length;         if (len == 0) {             System.out.print("无元素");             return;         }         for (int i = 0; i < len; i++) {             if (i == 0)                 System.out.print("(");              if (i == len - 1)                 System.out.print(arr[i] + ")");             else                 System.out.print(arr[i] + ",");         }      }      @SuppressWarnings("unchecked")     @Test     public void test()             throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {         Constructor<A> constructor = null;         try {             constructor = (Constructor<A>) Class.forName("T20190328.A")                     .getDeclaredConstructor(String.class, String.class);         } catch (NoSuchMethodException e) {             e.printStackTrace();         } catch (SecurityException e) {             e.printStackTrace();         } catch (ClassNotFoundException e) {             e.printStackTrace();         }         constructor.setAccessible(true);         constructor.newInstance("x", "y");     }      String clsPathFromXml() throws ParserConfigurationException, SAXException, IOException {         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 创建DOM解析器工厂对象         DocumentBuilder builder = factory.newDocumentBuilder(); // 创建DOM解析器对象         String path = this.getClass().getResource("om.xml").getPath();         Document doc = builder.parse(new File(path)); // 解析XML文档,并获取该XML文档的Document对象         Element component = doc.getDocumentElement(); // 获取根节点元素的Element对象         NodeList nodeList = component.getElementsByTagName("package");          Node pkg = nodeList.item(0);         Node pkgAttr = pkg.getAttributes()                 .getNamedItem("name");         String pkgName = pkgAttr.getNodeValue();         Node cls = pkg.getFirstChild();         String clsName = cls.getNodeValue();          return pkgName + "." + clsName;     }          @Test     public void testXml() {         try {             System.out.println(clsPathFromXml());         } catch (ParserConfigurationException | SAXException | IOException e) {             e.printStackTrace();         }     }          public static void main(String[] args) {         String className = null;         ClassTest ct = new ClassTest();         try {             className =ct.clsPathFromXml();         } catch (ParserConfigurationException | SAXException | IOException e1) {             e1.printStackTrace();         }         Constructor<A>[] constructors = null;         try {             constructors = cast(Class.forName(className) // 从类路径下加载并连接类T20190328.A                     .getDeclaredConstructors());         } catch (SecurityException | ClassNotFoundException e) {             e.printStackTrace();         }          AccessibleObject.setAccessible(constructors, true); // 批量授予访问私有访问权限          // 按类中定义的顺序输出构造器         for (int i = 0; i < constructors.length; i++) {             Constructor<A> constructor = constructors[i];             System.out.print(constructor + "--->");              // 构造器参数全部类型             Type[] types = constructor.getGenericParameterTypes();              int typeNum = types.length;              showTypes(types);             System.out.print("===>");              // constructor.setAccessible(true); // 允许私有访问权限, 否则无法实例化对象              // 实例化对象             A a;             try {                 if (typeNum == 1) {                     a = (A) constructor.newInstance(1);                     a.b();                 } else if (typeNum == 2) {                     a = (A) constructor.newInstance("hello", "world");                     a.b();                 } else {                     a = (A) constructor.newInstance();                     a.b();                 }                 list.add(a);             } catch (InstantiationException | IllegalAccessException | IllegalArgumentException                     | InvocationTargetException e) {                 e.printStackTrace();             }          }          // 打印生成对象的内存地址哈希值         for (A a : list) {             System.out.println(a);         }     }  }  class A extends B {      private A(String x, String y) {         System.out.println("has two params : " + x + "," + y);     }      private A(int i) {         System.out.println("has one param : " + i);     }      private A() {         System.out.println("has zero param");     }  //    private A(String... strings) { //        System.out.println(strings); //    }      public void a() {         System.out.println("A");     } }  class B {     String name;     int age;          public void b() {         System.out.println("B");     } } om.xml
<?xml version="1.0" encoding="UTF-8"?> <component> <package name="T20190328"> <class>A </class> </package> </component>
问题来源:
https://www.nowcoder.com/questionTerminal/a3f14638ac2e432b884351840f42d80f?toCommentId=1111154