先说构造方法,在使用Class类中的,newInstance() 取得实例化对象时,会出现一些问题。看下面出错的代码:
package com.jmd.bingo; class Person { private String name; private int age; // public Person() { // this.name = "bingo"; // this.age = 21; // } public Person(String name,int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String toString() { return "name:"+ this.name+",age:"+this.age; } } public class Fs { public static void main(String[] args) { Class<?> cls; try { cls = Class.forName("com.jmd.bingo.Person");//通过反射实例化Person类对象。 Person p = (Person)cls.newInstance(); System.out.println(p); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
错误提示:
出错的原因是Person类没有提供无参构造函数,最简单的解决办法就是把写一个无参构造。那么,我就不写呢?办法还是有的。看上面的报错信息:”at java.lang.Class.getConstructor0(Unknown Source)“ 可知Class类中有个getConstructor()方法,可以找到构造方法。那么就在getConstructor()上动动手脚。给它明确指定构造方法。
public class Fs { public static void main(String[] args) { Class<?> cls; try { cls = Class.forName("com.jmd.bingo.Person");//通过反射实例化Person类对象。 Constructor<?> cons = cls.getConstructor(String.class,int.class); Person p = (Person)cons.newInstance("张三",18); System.out.println(p); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
getConstructor()方法的参数是,被指定的构造方法的参数类型.class。通过Constructor对象的newInstance()方法去实例化对象。 还是挺麻烦的吧,所以,类中一定要写无参构造。
反射调用一般方法:
类中的一般方法的调用一定是在实例化该类对象之后调用的,反射也不例外。getMethod() 取得方法,invoke()方法执行函数。 下面代码实现了,只给定类名,和属性名,设置相关属性。一定要用到反射。
public Method getMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException
参数分别是 方法名,参数类型
public Object invoke(Object obj, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException 参数是 执行方法的对象,和方法的参数
package com.jmd.bingo; import java.lang.reflect.Method; class Person { private String name; private int age; public Person() { } public Person(String name,int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String toString() { return "name:"+ this.name+",age:"+this.age; } } public class Fs { public static void main(String[] args) throws Exception { String attribute = "name"; //方法名中的N大写,后面转换。 Class<?> cls = Class.forName("com.jmd.bingo.Person");//通过反射实例化Person类对象。 Person p = (Person)cls.newInstance(); Method setMethod = cls.getMethod("set"+upper(attribute), String.class); //方法名,参数类型 Method getMethod = cls.getMethod("get"+upper(attribute)); setMethod.invoke(p, "张三"); System.out.println(getMethod.invoke(p)); } public static String upper(String str) { return str.substring(0,1).toUpperCase() + str.substring(1); } }
最终输出: 张三