什么是反射?书上是这样定义的:“在Java中的反射机制是指在运行状态中,对于任意一个类都能够知道这个类所有的属性和方法;并且对于任意一个对象,都能够调用它的任意一个方法;这种动态获取信息以及动态调用对象方法的功能成为Java语言的反射机制”。
要想了解反射,必须了解这四种API:
Class类:反射的核心类,可以获取类的Constructor,Method和Field属性。(注意:不要和class关键字搞混)
Constructor类:Java.lang.reflec包中的类,表示类中的构造方法。
Method类:Java.lang.reflec包中的类,表示类中的成员方法。
Field类:Java.lang.reflec包中的类,表示类中的成员变量。
下面我将根据API从四个方面讲一下反射的基本应用,先定义一个父子类:
package com.Jevin.blog;
public class Person {
/**
* 成员变量:
*/
public String name;
protected int age;
String id;
private String weight;
/**
* 成员方法:
*/
public void love(){
System.out.println("每个人都有追求爱的权利!");
}
protected void makeLove(){
System.out.println("所以我们都喜欢做爱!");
}
void romatic(){
System.out.println("爱情除了做,还需要浪漫!");
}
private void life(){
System.out.println("我们同样都需要生活!");
}
}
package com.Jevin.blog;
public class Student extends Person {
/**
* 成员变量:
*/
public String stuNo;
protected String className;
int score;
private String hobby;
/**
* 构造方法:
*/
public Student(){
System.out.println("共有的无参构造方法!");
}
public Student(String stuNo){
System.out.println("共有的带参数的构造方法stuNo="+stuNo);
}
protected Student(int score){
System.out.println("受保护的有参构造方法score="+score);
}
Student(String hobby,int score){
System.out.println("默认的有参构造方法hobby="+hobby+",score="+score);
}
private Student(String stuNo,String className,int score){
System.out.println("私有的构造方法:stuNo="+stuNo+",className="+className+",score="+score);
}
/**
* 成员方法:
*/
public void test(int a,boolean b){
System.out.println("作为学生,我们都需要考试!");
}
void getScore(String str){
System.out.println("还需要拿高分数!");
}
protected void hateScore(double d){
System.out.println("但是我们都讨厌分数!");
}
private void CEE(String eng){
System.out.println("但是不得不面对高考!");
}
}
一:创建反射的三种方式:
package com.Jevin.blog;
/**
* 创建反射类型的三种方式:
*/
public class ReflectType {
public static void main(String[] args) throws Exception {
//方式一:".class"
Class clazz1=Student.class;
//方式二:"Class.forName(String args)"
Class clazz2=Class.forName("com.Jevin.blog.Student");
//方式三:"引用.getClass()"
Student student=new Student();
Class clazz3=student.getClass();
}
}
二:利用反射获取类中的构造方法:
package com.Jevin.blog;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
/**
* 利用反射获取类中的构造方法:
*/
public class ConstructorTest {
public static void main(String[] args) throws Exception {
Class clazz=Class.forName("com.Jevin.blog.Student");
//1.通过"getConstructors()"获取当前类所有的public的构造方法:
/*Constructor[] constructors1=clazz.getConstructors();
for(Constructor constructor:constructors1){
*//**
* 结果:
* public com.Jevin.blog.Student(java.lang.String)
* public com.Jevin.blog.Student()
*//*
System.out.println(constructor);
*//**
* 结果:
* public com.Jevin.blog.Student(String arg0)
* public com.Jevin.blog.Student()
* 这样写也可以,但是有点麻烦,所以不建议;
*//*
//获取权限修饰符:
int mod=constructor.getModifiers();
String modifier=Modifier.toString(mod);
System.out.print(modifier+" ");
//获取方法名:
String methodName=constructor.getName();
System.out.print(methodName+"(");
//获得参数:
Class[] cArgs=constructor.getParameterTypes();
for(int i=0;i<cArgs.length;i++){
System.out.print(cArgs[i].getSimpleName()+" arg"+i);
if(i<cArgs.length-1){
System.out.print(",");
}
}
System.out.print(")");
System.out.println();
}*/
//2.通过"getDeclaredConstructors()"获取本类中所有的构造方法,包括public,protected,default,private;
/**
* 结果:
* private com.Jevin.blog.Student(java.lang.String,java.lang.String,int)
* com.Jevin.blog.Student(java.lang.String,int)
* protected com.Jevin.blog.Student(int)
* public com.Jevin.blog.Student(java.lang.String)
* public com.Jevin.blog.Student()
*/
/*Constructor[] constructors=clazz.getDeclaredConstructors();
for(Constructor constructor:constructors){
System.out.println(constructor);
}*/
//3.通过"getConstructor(class... paramterType)"获得指定的含有特定参数的public构造方法:
/**
* 结果:
* public com.Jevin.blog.Student(java.lang.String)
*/
//Constructor constructor=clazz.getConstructor(String.class);
//System.out.println(constructor);
//4.通过"getDeclaredConstructor(Class... paramterType)"获取本类中指定的含有特定参数的构造方法:
//Constructor constructor=clazz.getDeclaredConstructor(int.class);
/**
* 结果:
* protected com.Jevin.blog.Student(int)
*/
//System.out.println(constructor);
//5.那么,能否获得private修饰的构造方法呢?
Constructor constructor= clazz.getDeclaredConstructor(String.class,String.class,int.class);
/**
* 结果:private com.Jevin.blog.Student(java.lang.String,java.lang.String,int)
* 答案是可以的。
*
*/
System.out.println(constructor);
//实例化对象:
/**
* 结果:
* 私有的构造方法:stuNo=702,className=三中,score=59
* com.Jevin.blog.Student@4554617c
*/
constructor.setAccessible(true);
Student student=(Student)constructor.newInstance("702","三中",59);
System.out.println(student);
}
}
三:利用反射获取类中的成员变量:
package com.Jevin.blog;
import java.lang.reflect.Field;
/**
* 利用反射获取类中的成员变量:
* 四种:getFields(),getField(String arg),getDeclaredFields(),getDeclaredField(String arg);
*/
public class VariableTest {
public static void main(String[] args) throws Exception {
Class clazz=Class.forName("com.Jevin.blog.Student");
/**
* 1.利用getFeilds()获取本类及其父类中所有public修饰的成员方法:
*
* 结果:public java.lang.String com.Jevin.blog.Student.stuNo
* public java.lang.String com.Jevin.blog.Person.name
*/
/*Field[] fields=clazz.getFields();
for(Field field:fields){
System.out.println(field);
}*/
/**
* 2.利用getField(String arg)获取本类中指定的public修饰的成员方法:
*
* 结果:public java.lang.String com.Jevin.blog.Student.stuNo
*/
/*Field field=clazz.getField("stuNo");
System.out.println(field);*/
/**
* 3.利用getDeclaredFields()获取本类中所有的成员变量:包括public,protected,default,private修饰的:
*
* 结果:
* public java.lang.String com.Jevin.blog.Student.stuNo
* protected java.lang.String com.Jevin.blog.Student.className
* int com.Jevin.blog.Student.score
* private java.lang.String com.Jevin.blog.Student.hobby
*/
/*Field[] fields=clazz.getDeclaredFields();
for(Field field:fields){
System.out.println(field);
}*/
/**
* 4.利用getDeclaredField(String arg)获取本类中指定的成员变量,不论是public,protected,defaul,private中的哪一种。
*
* 结果:private java.lang.String com.Jevin.blog.Student.hobby
*/
Field field=clazz.getDeclaredField("hobby");
System.out.println(field);
}
}
四:利用放射获取类中的成员方法:
package com.Jevin.blog;
import java.lang.reflect.Method;
/**
*利用反射类型获取成员方法:
* 四种:getMethods(),getMethod(String arg,Class... paramterType),getDeclaredMethods(),getDeclaredMethod(String arg,Class... paramterType)
*/
public class MethodTest {
public static void main(String[] args) throws Exception {
Class clazz=Class.forName("com.Jevin.blog.Student");
/**
* 1.利用getMethods()获取本类中及其父类中所有的public修饰的成员方法:
*
* 结果:public void com.Jevin.blog.Student.test(int,boolean)
* public void com.Jevin.blog.Person.love()
* 当然这里还有从Object父类中继承来的public方法,这里就不写了。
*/
/*Method[] methods=clazz.getMethods();
for(Method method:methods){
System.out.println(method);
}*/
/**
* 2.利用getMethod(String arg,Class... paramterType)获取本类中public修饰的成员方法
* 第一个参数表示:方法名
* 第二个参数表示:方法中参数的反射类型
*
* 结果:public void com.Jevin.blog.Student.test(int,boolean)
*/
/*Method method=clazz.getMethod("test",int.class,boolean.class);
System.out.println(method);*/
/**
* 3.利用getDeclaredMethods()获取本类中所有权限的成员方法,包括public,private,protected,default
*
* 结果:
* public void com.Jevin.blog.Student.test(int,boolean)
* void com.Jevin.blog.Student.getScore(java.lang.String)
* private void com.Jevin.blog.Student.CEE(java.lang.String)
* protected void com.Jevin.blog.Student.hateScore(double)
*/
/*Method[] methods=clazz.getDeclaredMethods();
for(Method method:methods){
System.out.println(method);
}*/
/**
* 4.利用getDeclaredMethod(String arg,Class... paramterType)货期本类中任意权限下的成员方法
*
* 结果:private void com.Jevin.blog.Student.CEE(java.lang.String)
*/
Method method=clazz.getDeclaredMethod("CEE",String.class);
System.out.println(method);
}
}
//如果我要利用放射调用Student类中的getScore(String str)方法
@Test
public void test(){
Class clazz = Student.class;
Student student = (Student)clazz.newInstance();
//第一个参数是String类型,表示调用的方法名称。
//第二个参数是这个调用方法的参数的Class对象
Method method = clazz.getMethod("getScore", String.class);
//invoke方法,第一个参数是该方法所在类的对象。
//第二个参数是该方法参数的对象
method.invoke(student, new String());
}
好了,大致上最基本的就这些了。其他的更高深的等以后段位高了再发吧!