经过前面的一篇博客,Java—类反射(1),相信大家对类反射有了一定的了解了。
下面来进行对类反射的加强,了解一下怎么通过类反射去new一个对象,
怎么通过类反射去访问其他类的方法。
怎么通过类反射去访问其他类的成员变量。
大家也许认为一个类的私有方法,私有的成员变量是其他类访问不到。但是,类反射是可以通过暴力访问去访问的。
还有:最后要模拟Java内省的功能
类的调用(调用类中的成员)
★ 构造类对象
使用构造器新建对象。根据指定的参数类型找到相应的构造函数,传入相应参数调用执行,以创建一个新的对象实例。
代码示例
Person类代码:
package cn.hncu.reflect; import java.io.IOException; /** * @author 陈浩翔 * * @version 1.0 2016-5-2 */ public class Person extends Parent { String name; private int age; public int num; public static String schoolName; public Person() { this("naName", 0); } public Person(String name, int age) { this.name = name; this.age = age; } public Person(int age) throws IOException, NumberFormatException { this("naName", age); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } protected void setAge(int age) { this.age = age; } private int sum(int a) { return 0; } private int sum() { return 0; } int aa(String a, int b) throws IOException, NumberFormatException { return 0; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", num=" + num + "]"; } } class Parent{ public static final int N=100; }
构造类对象:
package cn.hncu.reflect; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; /** * 类反射的演示 * @author 陈浩翔 * * @version 1.0 2016-5-2 */ public class ReflectOperateObj { private static final String CLASS_FILE_NAME="cn.hncu.reflect.Person"; public static void main(String[] args) { try { operateConstructor(CLASS_FILE_NAME); } catch (ReflectiveOperationException e) { e.printStackTrace(); } } /** * 一、演示:使用构造器来新建对象 * @param classFileName * @throws ReflectiveOperationException */ private static void operateConstructor(String classFileName) throws ReflectiveOperationException { Class cls = Class.forName(CLASS_FILE_NAME); //1 无参构造方法的使用----简单且以后用得最多的 //Object obj = cls.newInstance(); //2 有参构造方法的使用 //用类反射的方式来执行 Object obj = new Person("Jack",20); //2.1获取指定"参数列表类型"的构造器---Constructor对象 Class parameterTypes[] = new Class[2]; parameterTypes[0] = String.class; parameterTypes[1] = int.class; Constructor con= cls.getConstructor(parameterTypes);//※1※ //2.2调用构造器来new对象 Object initargs[] = new Object[2]; initargs[0] = new String("Jack"); initargs[1] = new Integer(20); Object resultObj = con.newInstance(initargs);//※2※ System.out.println(resultObj); } }
输出结果:
Person [name=Jack, age=20, num=0]
★ 调用方法
根据方法名称执行方法。根据方法名与参数类型匹配指定的方法,传入相应参数与对象进行调用执行。若是静态方法,则不需传入具体对象。
代码示例:
Person还是之前的Person类…
演示:调用无参普通方法:
package cn.hncu.reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Method; /** * 类反射的演示 * @author 陈浩翔 * * @version 1.0 2016-5-2 */ public class ReflectOperateObj { private static final String CLASS_FILE_NAME="cn.hncu.reflect.Person"; public static void main(String[] args) { try { callMethod(CLASS_FILE_NAME); } catch (ReflectiveOperationException e) { e.printStackTrace(); } } /** * 二、演示:调用无参普通方法 * @param classFileName * @throws ReflectiveOperationException */ private static void callMethod(String classFileName) throws ReflectiveOperationException{ Class cls = Class.forName(CLASS_FILE_NAME); //需求:调用空参方法 p.toString() //1.1必须要用一个类对象 Object obj = cls.newInstance(); //1.2用对象来调方法 //1.2.1先拿到对应方法的Method对象 Method m = cls.getMethod("toString", null); //1.2.2用obj和method来调用该方法 Object returnValue = m.invoke(obj, null); System.out.println(returnValue); } }
输出结果:
Person [name=naName, age=0, num=0]
演示:调用有参普通方法
Person相比之前,加了一个double sum(int , double)方法。
public double sum( int n, double d){ double sum =0; for(int i=1;i<=n;i++){ sum +=d; } return sum; }
演示类:
package cn.hncu.reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Method; /** * 类反射的演示 * @author 陈浩翔 * * @version 1.0 2016-5-2 */ public class ReflectOperateObj { private static final String CLASS_FILE_NAME="cn.hncu.reflect.Person"; public static void main(String[] args) { try { callMethod2(CLASS_FILE_NAME); } catch (ReflectiveOperationException e) { e.printStackTrace(); } } /** * 三、演示:调用有参普通方法 * @param classFileName * @throws ReflectiveOperationException */ private static void callMethod2(String classFileName) throws ReflectiveOperationException{ Class cls = Class.forName(CLASS_FILE_NAME); //需求:调用有参方法 p.sum(10,2.34) //1.1必须要用一个类对象 Object obj = cls.newInstance(); //**1.2用对象来调方法 //***1.2.1先拿到对应方法的Method对象 Class parameterTypes[] = new Class[2];//形参列表---类型列表---Class数组 //paramTypes[0]=int.class;//OK parameterTypes[0]=Integer.TYPE;//OK //paramTypes[0]=Integer.class;//ERROR: 因为Integer.class对应的是Integer类型,不是int类型。而Integer.TYPE是指int类型 parameterTypes[1]=double.class; Method method = cls.getMethod("sum", parameterTypes); //***1.2.2用obj和method来调用该方法 Object[] args = new Object[2]; args[0] = 10; args[1] = 2.34; Object returnObj = method.invoke(obj, args); System.out.println(returnObj); } }
输出结果:
23.4 • 1 • 2
演示:调用静态方法
Person类加了一个静态方法show();
public static void show(){ System.out.println("show........."); }
演示类:
package cn.hncu.reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Method; /** * 类反射的演示 * @author 陈浩翔 * * @version 1.0 2016-5-2 */ public class ReflectOperateObj { private static final String CLASS_FILE_NAME="cn.hncu.reflect.Person"; public static void main(String[] args) { try { callMethod3(CLASS_FILE_NAME); } catch (ReflectiveOperationException e) { e.printStackTrace(); } } /** * 四、演示:调用静态方法---不需要对象就可以调,其它的跟普通方法一样 * @param classFileName * @throws ReflectiveOperationException */ private static void callMethod3(String classFileName) throws ReflectiveOperationException{ Class cls = Class.forName(CLASS_FILE_NAME); //调用static show(); Method methed = cls.getMethod("show", null); methed.invoke(null, null); } }
输出结果:
show......... • 1 • 2