一.反射:
反射机制就是java程序在运行时拥有自观能力,能知晓类中的所有属性和方法。
通过反射能得到类中的任何属性和方法,也就是说反射可以打破类的封装特性,可以通过反射来调用私有方法。
让我们看个小例子:
public class Test {
public static void main(String[] args) throws Exception {
Class
classType = MethodTest.class;
Method[] method = classType.getDeclaredMethods();
for(Method m :method){
System.out.println(m);
}
}
}
public class MethodTest extends MethodTest2 {
public MethodTest(){}
public void methodOne(){
}
private void methodTwo(){
}
private String methodThree(){
return null;
}
public int methodFour(){
return 0;
}
}
打印:
public void Reflection3.MethodTest.methodOne()
private void Reflection3.MethodTest.methodTwo()
private java.lang.String Reflection3.MethodTest.methodThree()
public int Reflection3.MethodTest.methodFour()
这个小例子为我们显示MethodTest类中的所有方法,其中包括了私有方法和普通方法。要想使用反射就必须获得待处理类的class对象。
除了我上面MethodTest.class获取Class对象的方法还有两种,加上我用的一共三种方式:
1).使用Class类的静态方法forName:Class.forName("java.lang.String");
例子:
public>
会打印出String中的所有方法。
2).就是使用我第一个例子中的方法。类.class的方法。
3).使用对象的getClass()方法。
例子:
public class Test {
public static void main(String[] args) throws Exception {
String str = "abc";
Class
classType = str.getClass();
Method[] method = classType.getDeclaredMethods();
for(Method m :method){
System.out.println(m);
}
}
}
这个将会打印出String类中所有的方法。
如何通过反射使用类中的public类型方法:
public class Test {
public int sum(int a,int b){
return a + b;
}
public String Course(String str){
return "课程名:" + str;
}
public static void main(String[] args) throws Exception{
Class
classType = Test.class;
//通过classType.newInstance()来返回Test的实例对象,只能调用无参构造。
Object obj = classType.newInstance();
//第一个参数指定类中的方法名称,第二个参数指定其方法的参数类型,为什么会有第二个参数,因为类中会有重载的方法,用此来进行区分。
Method sumMethod = classType.getMethod("sum",int.class,int.class);
Object sum = sumMethod.invoke(obj,1,2);
System.out.println((Integer)sum);
System.out.println("==========================================");
Method courseMethod = classType.getMethod("Course",String.class);
Object course = courseMethod.invoke(obj,"Java");
System.out.println(course);
}
}
打印:
3
==========================================
课程名:Java
上面的例子中通过classType.newInstance()来获得Test的实例,但是这个方法只能调用无参的构造方法。使用方法时用通过invoke(传入方法存在类的实例,传入方法的参数)。
有参的构造方法使用格式:先获得Class对象,然后通过该对象获得相应的Constructor对象,再通过该Constructor对象的newInstance()方法生成。
如果想通过类的带参构造方法生成对象,只能使用下面例子中的格式。
例子:
public class Test {
public static void main(String[] args) throws Exception {
Class
classType = People.class;
/*
* Constructor con = classType.getConstructor(new Class[]{});
* Object obj = con.newInstance(new Object[]{});
* 也可以创建不带参数的对象。
*/
Constructor con = classType.getConstructor(String.class);
Object obj = con.newInstance("zhangsan");
System.out.println(obj);
}
}
class People {
private String name;
public People(){}
public People(String name){
this.name = name;
}
public String getName(){
return name;
}
}
如何通过反射使用类中的属性和方法:
例子:
public class ReflectionTest {
//执行对一个对象的copy操作。
public Object copy(Object o) throws Exception{
Class
cs = Student.class;
Object obj = cs.getConstructor(new Class[]{}).newInstance(new O