先说构造方法,在使用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);
}
}
最终输出: 张三