心得23--JDK新特性7-反射2-Filed、Construction类(构造方法)
1. Constructor类提供了如下方法,用于创建类的对象:
public Object newInstance(Object...initargs)
initargs用于指定构造函数接收的参数
多学一招:sun公司为简化开发人员创建对象,它在class对象中也提供了一个newInstance方法,用于创建类的对象。这样开发人员可以避免每次都需要去反射Constructor 类以创建对象。
不过需要注意的是:class.newInstance方法内部是反射类无参的构造函数创建的对象,所以利用此种方式创建类对象时,类必须有一个无参的构造函数。
具体案例分析
packagecom.java.reflect;
importjava.lang.reflect.Constructor;
importjava.lang.reflect.InvocationTargetException;
importorg.junit.Test;
publicclass Demo2 {
//@Test
//反射出无参的构建函数,并创建Person对象
publicvoid test1()throws ClassNotFoundException,NoSuchMethodException, SecurityException, InstantiationException,IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//加载类
Class c = Class.forName("com.java.reflect.Person");
//反射出构造方法
Constructor cs = c.getConstructor(null);
Person p = (Person)cs.newInstance(null);
System.out.println(p.getName());
//输出结果为:无参构造函数 zhangsan
}
//@Test
//反射出带一个参数的构建函数public Person(String name)
publicvoid test2()throws ClassNotFoundException, NoSuchMethodException,SecurityException, InstantiationException, IllegalAccessException,IllegalArgumentException, InvocationTargetException {
//加载类
Class c = Class.forName("com.java.reflect.Person");
//反射出构造方法
Constructor cs = c.getConstructor(String.class);
Person p = (Person)cs.newInstance("李四");
System.out.println(p.getName());
//输出结果为:李四 zhangsan 分析:第一个输出李四是调用的带参的构造方法,第一zhangsan是Person类中属性值,因为这个带参的构造方法中没有this.name = name 字样
}
//@Test
//反射出带两个参数的构建函数public Person(String name,int age)
publicvoid test3()throws ClassNotFoundException,NoSuchMethodException, SecurityException, InstantiationException,IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//加载类
Class c = Class.forName("com.java.reflect.Person");
//反射出构造方法
Constructor cs = c.getConstructor(String.class,int.class);
Person p = (Person)cs.newInstance("李四",20);
System.out.println(p.getName());
//输出结果为:李四.....20 zhangsan
}
@Test
//反射出私有构造函数(需要用getDeclaredConstructor()方法)
publicvoid test4()throws ClassNotFoundException,NoSuchMethodException, SecurityException, InstantiationException,IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//加载类
Class c = Class.forName("com.java.reflect.Person");
//反射出构造方法
Constructor cs = c.getDeclaredConstructor(int.class);
cs.setAccessible(true); //如果是私有的必须设置访问权限
Person p = (Person)cs.newInstance(60);
System.out.println(p.getName());
//输出结果为: 60zhangsan
}
@Test
//运用Class类的newInstance()方法来反射无参的构造方法
publicvoid test5()throws ClassNotFoundException,InstantiationException, IllegalAccessException {
//加载类
Class c = Class.forName("com.java.reflect.Person");
Person p = (Person)c.newInstance();
System.out.println(p.getName());
//输出结果为:无参构造方法zhangsan
}
}
2. Method对象提供了如下方法,用于执行它所代表的方法:
public Object invoke(Object obj,Object... args)
与Construction类即调用构造方法的时候基本一样:
具体案例:
packagecom.java.reflect;
importjava.lang.reflect.InvocationTargetException;
importjava.lang.reflect.Method;
importorg.junit.Test;
publicclass Demo3 {
/**
* @param args
* @throws ClassNotFoundException
* @throws SecurityException
* @throws NoSuchMethodException
* @throws InvocationTargetException
* @throws IllegalArgumentException
* @throws IllegalAccessException
*/
//@Test
// 调用无参方法public void run()
publicvoid test1()throws ClassNotFoundException,NoSuchMethodException,
SecurityException,IllegalAccessException,
IllegalArgumentException,InvocationTargetException {
Person p = new Person();
Class c = Class.forName("com.java.reflect.Person");
Method m = c.getMethod("run",null);
m.invoke(p, null);
// 输出结果:无参构造函数(因为调用了Person类的无参构造函数)run.......
}
//@Test
// 调用带一个参数的方法public void run(String name)
publicvoid test2()throws ClassNotFoundException, NoSuchMethodException,
SecurityException,IllegalAccessException,
IllegalArgumentException,InvocationTargetException {
Person p = new Person();
Class c = Class.forName("com.java.reflect.Person");
Method m = c.getMethod("run", String.class);
m.invoke(p, "杨凯");
// 输出结果:无参构造函数(因为调用了Person类的无参构造函数)run...杨凯
}
//@Test
// 调用带两个参数的方法public void run(int i,int j)
publicvoid test3()throws ClassNotFoundException,NoSuchMethodException,
SecurityException,IllegalAccessException,
IllegalArgumentException,InvocationTargetException {
Person p = new Person();
Class c = Class.forName("com.java.reflect.Person");
Method m = c.getMethod("sum",int.class,int.class);
System.out.println(m.invoke(p, 10, 20));
/*
* 以下输出结果一样 int value = (Integer) m.invoke(p,10,20);
*System.out.println(value);
*/
// 输出结果:无参构造函数(因为调用了Person类的无参构造函数)30
}
//@Test
// 调用私有方法prvate void sum()
publicvoid test4()throws ClassNotFoundException,NoSuchMethodException,
SecurityException,IllegalAccessException,
IllegalArgumentException,InvocationTargetException {
Person p = new Person();
Class c = Class.forName("com.java.reflect.Person");
Method m = c.getDeclaredMethod("sum",null);
m.setAccessible(true);
m.invoke(p, null);
// 输出结果:无参构造函数(因为调用了Person类的无参构造函数)private....
}
@Test
// 调用静态方法public static void run1()
publicvoid test5()throws ClassNotFoundException,NoSuchMethodException,
SecurityException, IllegalAccessException,
IllegalArgumentException,InvocationTargetException {
// Person p = newPerson(); 调用静态的方法可以不传入对象
Class c = Class.forName("com.java.reflect.Person");
Method m = c.getMethod("run1",null);
m.invoke(null,null);
// 输出结果:无参构造函数(因为调用了Person类的无参构造函数)private....
}
}