<-------------------------续----------------------->
用反射来创建对象实例若想通过类的不带参数的构造方法来生成对象,我们有两种方式:
先获得Class对象,然后通过该Class对象的newInstance()方法直接生成即可:
1 Class<?> classType = String.class; 2 Object obj = classType.newInstance();
先获得Class对象,然后通过该对象获得对应的Constructor对象,再通过该Constructor
对象的newInstance()方法生成:
1 Class<?> classType = Customer.class; 2 Constructor cons = classType.getConstructor(new Class[]{}); 3 Object obj = cons.newInstance(new Object[]{});
若想通过类的带参数的构造方法生成对象,只能使用下面这一种方式:
1 Class<?> classType = Customer.class; 2 Constructor cons = classType.getConstructor(new Class[]{String.class, int.class}); 3 Object obj = cons.newInstance(new Object[]{“hello”, 3});
反射经常用到的类Constructor、Method、Filed
Constructor 提供关于类的单个构造方法的信息以及对它的访问权限。
Method 提供关于类或接口上单独某个方法(以及如何访问该方法)的信息。所反映的方法可能是类方法或实例方法(包括抽象方法)。
1 import java.lang.reflect.Method; 2 3 public class MethodTest 4 { 5 public static void main(String[] args) throws Exception 6 { 7 Class<?> classes = Person1.class; 8 Method method = classes.getDeclaredMethod("getName"); 9 Person1 person = new Person1("tom",34); 10 System.out.println(method.invoke(person, null)); 11 System.out.println(method.invoke(person, new Object[]{})); 12 //调用静态方法 13 method = classes.getDeclaredMethod("methodStatic"); 14 System.out.println(method.invoke(null, new Object[]{})); 15 16 } 17 } 18 19 class Person1 20 { 21 private String name; 22 23 public Person1(String name, int age) 24 { 25 super(); 26 this.name = name; 27 } 28 29 public static void methodStatic() 30 { 31 System.out.println("my is static"); 32 } 33 34 public String getName() 35 { 36 return name; 37 } 38 39 public void setName(String name) 40 { 41 this.name = name; 42 } 43 }
invoke方法再说明:
public Object invoke(Object obj,Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
- 对带有指定参数的指定对象调用由此
Method对象表示的底层方法。个别参数被自动解包,以便与基本形参相匹配,基本参数和引用参数都随需服从方法调用转换。如果底层方法是静态的,那么可以忽略指定的
obj参数。该参数可以为 null。如果底层方法所需的形参数为 0,则所提供的
args数组长度可以为 0 或 null。如果底层方法是实例方法,则使用动态方法查找来调用它,这一点记录在 Java Language Specification, Second Edition 的第 15.12.4.4 节中;在发生基于目标对象的运行时类型的重写时更应该这样做。
如果底层方法是静态的,并且尚未初始化声明此方法的类,则会将其初始化。
如果方法正常完成,则将该方法返回的值返回给调用者;如果该值为基本类型,则首先适当地将其包装在对象中。但是,如果该值的类型为一组基本类型,则数组元素不 被包装在对象中;换句话说,将返回基本类型的数组。如果底层方法返回类型为 void,则该调用返回 null。
Field 提供有关类或接口的单个字段的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)字段或实例字段。
1 public class FieldTest 2 { 3 public static void main(String[] args) throws Exception 4 { 5 ReflectPoint pt1 = new ReflectPoint(10, 3); 6 7 Field fieldy = pt1.getClass().getField("y"); 8 System.out.println(fieldy.get(pt1)); 9 Field fieldx = pt1.getClass().getDeclaredField("x"); //当该属性是private的时用,
10 fieldx.setAccessible(true); 11 System.out.println(fieldx.get(pt1)); 12 } 13 } 14 15 class ReflectPoint 16 { 17 private int x; 18 public int y; 19 20 public ReflectPoint(int x, int y) 21 { 22 super(); 23 this.x = x; 24 this.y = y; 25 } 26 }
说明一下:用反射得到Class对象,在通过Class对象得到Field对象,当该属性是private的时用getDeclaredField("y");并且要调用field类中的fieldx.setAccessible(true);
意思是:将此对象的 accessible 标志设置为指示的布尔值。值为 true 则指示反射的对象在使用时应该取消 Java
语言访问检查。值为 false 则指示反射的对象应该实施 Java 语言访问检查。
注意:constructor,method,field都继承于accessibleObjec类,所以都有setAccessible方法,都可以压制java的语言访问检查。
浙公网安备 33010602011771号