关于反射 其实java给出了一个软件包,初学的话看api就能够看懂
api中在lang包下面有个软件包 java.lang.reflect 这个包提供类和接口,以获取关于类和对象的反射信息。
下面举个例子:
首先我们建立一个Student类,在这个类里面我们随便的创建了些字段和方法,待会我们通过另一个类通过反射的原理来取这个类里面的公共字段已经公共的方法。
public class Student {
public String name;
public int age;
public int sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
public Student() {
System.out.println("创建Student类!");
}
public void sayHello(){
System.out.println("Hello!");
}
public void sayHello(String name ){
System.out.println("Hello"+name+"!");
}
public void sayHello(int name ){
System.out.println("Hello"+name+"!");
}
}
在创建一个带主函数的类ReflectionMain 这个类里面我们就要应用java.lang.reflect这个包里面的一些方法。
/**
* @Title: ReflectionMain.java
* @Package com.javabasic.reflection
* @Description: TODO(用一句话描述该文件做什么)
* @author Yangjing
* @date 2014-5-8 下午2:41:40
* @version V1.0
*/
package com.javabasic.reflection;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* @ClassName: ReflectionMain
* @Description: TODO(这里用一句话描述这个类的作用)
* @author Yangjing
* @date 2014-5-8 下午2:41:40
*
*/
public class ReflectionMain {
/**
* @Title: main
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param @param args 设定文件
* @return void 返回类型
* @throws
*/
public static void main(String[] args) {
System.out.println("--------分-----割-----线-----开-----始--------");
//首先我们通过class的属性获得Student类的地址<这个地址是包括类所在的包名,这个相信大家都是很清楚的>
System.out.println(Student.class);
System.out.println("--------分-----割-----线-----结-----束--------");
System.out.println("--------分-----割-----线-----开-----始--------");
//我们再试试使用class里面的一个getName方法看看有什么不一样的效果
System.out.println(Student.class.getName());
//class里面的getName方法是 以 String 的形式返回此 Class 对象所表示的实体(类、接口、数组类、基本类型或 void)名称。
System.out.println("--------分-----割-----线-----结-----束--------");
System.out.println("--------分-----割-----线-----开-----始--------");
try {
//其实以往我们都是通过new的形式获得实例(对象)的,现在我们也可以通过Class里面的firName方法获得这个Class对象
Class clazz = Class.forName(Student.class.getName());
//class里面的forName方法:返回与带有给定字符串名的类或接口相关联的 Class 对象
//获得了Class对象后我们可以通过class的另一个方法获得该类的实例对象这个方法就是newInstance (创建Class对象所表示的类的一个新实例)。
Student stu = (Student) clazz.newInstance();
//输出来看的话,会看到他输出了构造函数里面输出语句并且还输出了他在内存空间的地址
System.out.println(stu);
//既然我们已经通过这种形式拿到了Student的实例,那我们就能够去拿到它里面的公共方法以及他父类的公共方法和他里面的公共字段
//这个就要用到反射包里面的方法了
System.out.println("--------分-----割-----线-----结-----束--------");
System.out.println("--------分-----割-----线-----开-----始--------");
//获得Student类里面的方法<其中包含了它父类Object里面的方法>
Method[] met = clazz.getMethods();
for (Method method : met) {
System.out.println(method.getName());
}
System.out.println("--------分-----割-----线-----结-----束--------");
System.out.println("--------分-----割-----线-----开-----始--------");
//获得Student类里面自己的方法
Method[] met2 = clazz.getDeclaredMethods();
for (Method method : met2) {
System.out.println(method.getName());
}
System.out.println("--------分-----割-----线-----结-----束--------");
System.out.println("--------分-----割-----线-----开-----始--------");
//获得Student类父类里面的所有方法
Method[] met3 = clazz.getSuperclass().getMethods();
for (Method method : met3) {
System.out.println(method.getName());
}
System.out.println("--------分-----割-----线-----结-----束--------");
System.out.println("--------分-----割-----线-----开-----始--------");
//获得Student类里面指定的方法;getMethod方法第一个参数:你指定的方法名,第二个:可变参数列表(指定方法里面的参数列表)
Method met4 = clazz.getMethod("sayHello", null);
System.out.println(met4.getName()+"( )");
//调用拿到的这个方法 第一个参数是一个实例
met4.invoke(clazz.newInstance(), null);
System.out.println("--------分-----割-----线-----结-----束--------");
System.out.println("--------分-----割-----线-----开-----始--------");
//获得Student类里面指定的sayHello(带参)方法;getMethod方法第一个参数:你指定的方法名,第二个:可变参数列表(指定方法里面的参数列表)
Method met5 = clazz.getMethod("sayHello", new Class[]{java.lang.String.class});
//这么的意思是指去寻找Student类里面参数是String类型的sayHello方法
System.out.println(met5.getName()+"(String name)");
//调用拿到的这个方法 第一个参数是一个实例 第二个参数是该方法的参数
met5.invoke(clazz.newInstance(), new Object[]{" Neil"});
System.out.println("--------分-----割-----线-----结-----束--------");
System.out.println("--------分-----割-----线-----开-----始--------");
//获得Student类里面指定的sayHello(带参)方法;getMethod方法第一个参数:你指定的方法名,第二个:可变参数列表(指定方法里面的参数列表)
Method met6 = clazz.getMethod("sayHello", new Class[]{int.class});
//这么的意思是指去寻找Student类里面参数是int类型的sayHello方法
System.out.println(met6.getName()+"(int name)");
//调用拿到的这个方法 第一个参数是一个实例 第二个参数是该方法的参数
met6.invoke(clazz.newInstance(), new Object[]{ 1001});
System.out.println("--------分-----割-----线-----结-----束--------");
System.out.println("--------分-----割-----线-----开-----始--------");
//获得Student类里面的所有公共的字段
Field[] fie1 = clazz.getFields();
for (Field field : fie1) {
System.out.println(clazz.getName()+"里面的公共字段:"+field.getName());
}
System.out.println("--------分-----割-----线-----结-----束--------");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
这个就是一个简单的反射,其实在eclipse里面快捷键ctrl+o就是利用反射的原理;
下面这个是运行了的结果:
--------分-----割-----线-----开-----始--------
class com.javabasic.reflection.Student
--------分-----割-----线-----结-----束--------
--------分-----割-----线-----开-----始--------
com.javabasic.reflection.Student
--------分-----割-----线-----结-----束--------
--------分-----割-----线-----开-----始--------
创建Student类!
com.javabasic.reflection.Student@1034bb5
--------分-----割-----线-----结-----束--------
--------分-----割-----线-----开-----始--------
getName
setName
sayHello
sayHello
sayHello
getAge
setAge
getSex
setSex
wait
wait
wait
equals
toString
hashCode
getClass
notify
notifyAll
--------分-----割-----线-----结-----束--------
--------分-----割-----线-----开-----始--------
getName
setName
sayHello
sayHello
sayHello
getAge
setAge
getSex
setSex
--------分-----割-----线-----结-----束--------
--------分-----割-----线-----开-----始--------
wait
wait
wait
equals
toString
hashCode
getClass
notify
notifyAll
--------分-----割-----线-----结-----束--------
--------分-----割-----线-----开-----始--------
sayHello( )
创建Student类!
Hello!
--------分-----割-----线-----结-----束--------
--------分-----割-----线-----开-----始--------
sayHello(String name)
创建Student类!
Hello Neil!
--------分-----割-----线-----结-----束--------
--------分-----割-----线-----开-----始--------
sayHello(int name)
创建Student类!
Hello1001!
--------分-----割-----线-----结-----束--------
--------分-----割-----线-----开-----始--------
com.javabasic.reflection.Student里面的公共字段:name
com.javabasic.reflection.Student里面的公共字段:age
com.javabasic.reflection.Student里面的公共字段:sex
--------分-----割-----线-----结-----束--------
作者:杨静(YangJing)
出处: [ 杨静の专栏] ( 博文连接)