A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

无论是哪个的newInstance都是用来创建对象的。

①构造方法Constructor的newInstance()使用时,要传入参数,这个参数要与获得constructor(即使用getConstructor获得)时的一样。而Class 的newInstance()没有参数。因此,就要求Class对象的这个类要明确有无参的构造函数。

②假如一个类,没有写构造函数,那么会被自动加上一个无参的构造函数,是可以使用Class的newInstance的。

③如果类中有且都是非空参数的构造函数,那么就不能使用。除非在类中明确写出这个空参构造函数。

下面通过代码来验证。

代码示例:验证①

  1. package com.asin;

  2. import java.lang.reflect.Constructor;

  3. public class ReflectTest {
  4.         public static void main(String[] args) throws Exception {

  5.                 Constructor constructor1=String.class.getConstructor(StringBuffer.class);
  6.                 String string = (String)constructor1.newInstance(new StringBuffer("abc"));
  7.                 System.out.println(string);
  8.         }
  9. }
复制代码

运行结果:abc


如果第二个参数与第一次的不一样,将第二个的参数改成String对象

  1. Constructor constructor1=String.class.getConstructor(StringBuffer.class);
  2. String string = (String)constructor1.newInstance("abc");
  3. System.out.println(string);
复制代码

则会报错:



Exception in thread "main" java.lang.IllegalArgumentException: argument type mismatch

抛出的异常表明向方法传递了一个不合法或不正确的参数。



验证②:一个类,没有写构造函数,那么会被自动加上一个无参的构造函数,是可以使用Class的newInstance的。

  1. package com.asin;

  2. import java.lang.reflect.Constructor;

  3. public class ReflectTest {
  4.         public static void main(String[] args) throws Exception {

  5.                 Person per = Person.class.newInstance();
  6.                 System.out.println(per);
  7.                                
  8.         }
  9. }
  10. class Person
  11. {
  12.         String name;
  13.         int age;
  14.        
  15. }
复制代码

运行结果:

com.asin.Person@1aaf64d



验证③:如果类中有且都是非空参数的构造函数,那么就不能使用。除非在类中明确写出这个空参构造函数。

  1. package com.asin;

  2. import java.lang.reflect.Constructor;

  3. public class ReflectTest {
  4.         public static void main(String[] args) throws Exception {

  5.                 Person per = Person.class.newInstance();
  6.                 System.out.println(per);
  7.                                
  8.         }
  9. }
  10. class Person
  11. {
  12.         String name;
  13.         int age;
  14.        
  15.         public Person(String name, int age) {
  16.                
  17.                 this.name = name;
  18.                 this.age = age;
  19.         }
  20.        
  21. }
复制代码

运行报错:

Exception in thread "main" java.lang.InstantiationException: com.asin.Person

帮助文档说明:

InstantiationException - 如果此Class 表示一个抽象类、接口、数组类、基本类型或 void; 或者该类没有 null 构造方法; 或者由于其他某种原因导致实例化失败。

修改代码为:

  1. package com.asin;

  2. import java.lang.reflect.Constructor;

  3. public class ReflectTest {
  4.         public static void main(String[] args) throws Exception {

  5.                 Person per = Person.class.newInstance();
  6.                 System.out.println(per);
  7.                                
  8.         }
  9. }
  10. class Person
  11. {
  12.         String name;
  13.         int age;
  14.        
  15.        
  16.         public Person() {
  17.                
  18.         }

  19.         public Person(String name, int age) {
  20.                 this.name = name;
  21.                 this.age = age;
  22.         }
  23.        
  24. }
复制代码

运行结果:com.asin.Person@1aaf64d



演示:用这两种方法实例化一个String对象
String(byte[] bytes)
通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String。

  1. //方法一(前提是类中有空参数构造函数,比如Integer就不能这样实例化)
  2. //声明String对象str1
  3. String str1 = (String)Class.forName("java.lang.String").newInstance();       
  4. //给str1赋值
  5. str1 = new String(new byte[]{1,2,3});        
  6.                
  7. //方法二
  8. //得到String的传入字节数组参数的构造方法
  9. Constructor constructor = Class.forName("java.lang.String").getConstructor(byte[].class);
  10. //声明并赋值       
  11. String str2 = (String)constructor.newInstance(new byte[]{1,2,3});
复制代码



1 个回复

正序浏览
asinzuo 来自手机 中级黑马 2015-9-4 19:01:19
沙发
本帖最后由 asinzuo 于 2018-5-14 21:55 编辑

以后再用反射得到对象,就不需要先得到构造方法对象,可以省几行代码。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马