1、反射是什么
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
2、相关类
Class类与java.lang.reflect 类库一起对反射的概念进行了支持,该类库包含了Field、Method以及Constructor类,他们都实现了Member接口。
Constructor
方法简介:
getConstructors()返回一个数组,此Class
对象所表示的类的所有公共构造方法
getDeclaredConstructors() 返回一个数组,此 Class
对象表示的类声明的所有构造方法
getDeclaredConstructor(Class<?>... parameterTypes) 返回一个 Constructor
对象,该对象反映此 Class
对象所表示的类或接口的指定构造方法。
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class TestConstructor {
/**
* @param args
*/
public static void main(String[] args) throws Exception {
Class clazz = Class.forName("com.java.DemoConstructor");
//1只能获取到public 修饰的 构造器
Constructor[] con = clazz.getConstructors();
for (Constructor c : con)
System.out.println(c);
System.out.println("-------");
//2获取该类下所有的构造器
Constructor[] cons = clazz.getDeclaredConstructors();
for (Constructor c : cons)
System.out.println(c);
System.out.println("-----分割线1======");
//3、获取指定参数类型的构造器
Constructor cons2 = clazz.getDeclaredConstructor(int.class);
//获取权限
cons2.setAccessible(true);
//通过newInstance 来获取实例
DemoConstructor dc = (DemoConstructor)cons2.newInstance(1);
System.out.println(dc);
}
}
class DemoConstructor{
private String str;
private int i;
public DemoConstructor() {
}
public DemoConstructor(String str) {
this.str = str;
}
private DemoConstructor(int i) {
this.i = i;
}
public String toString() {
return "i = " + i + "--str = " + str;
}
}
结果输出:
public com.java.DemoConstructor(java.lang.String)
public com.java.DemoConstructor()-------
private com.java.DemoConstructor(int)
public com.java.DemoConstructor(java.lang.String)
public com.java.DemoConstructor()
-----分割线1======
i = 1--str = null
Method 类
方法简介:
getDeclaredMethod(String name, Class<?>... parameterTypes) 返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。
getDeclaredMethods() 返回一个数组,表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。
getMethods() 获取运行时类及其父类中所有的声明为public的方法,返回一个数组
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import org.junit.Test;
public class TestMethod {
/**
* @param args
*/
public static void main(String[] args) {
}
@Test public void test() {
Class clazz = MethodDemo.class;
//1.getMethods():获取运行时类及其父类中所有的声明为public的方法,返回一个数组
Method[] m = clazz.getMethods();
for(Method m1 : m)
System.out.println(m1.getName());
System.out.println("-----------------------");
//2.getDeclaredMethods():获取运行时类本身声明的所有的方法
Method[] m2 = clazz.getDeclaredMethods();
for(Method m1 : m2)
System.out.println(m1.getName());
}
@Test
public void test2(){
Class clazz = MethodDemo.class;
Method[] m2 = clazz.getDeclaredMethods();
for(Method m : m2){
//1.注解
Annotation[] ann = m.getAnnotations();
for(Annotation a : ann){
System.out.println(m.getName() + "--Annotation--" + a);
}
//2.权限修饰符
String str = Modifier.toString(m.getModifiers());
System.out.println(m.getName() + "--Modifier--" + str + " ");
//3.返回值类型
Class returnType = m.getReturnType();
System.out.println(m.getName() + "--returnType--" + returnType.getName() + " ");
//4.方法名
System.out.println(m.getName() + " ");
//5.形参列表
System.out.print("(");
Class[] params = m.getParameterTypes();
for(int i = 0;i < params.length;i++){
System.out.print(params[i].getName() + " args-" + i + " ");
}
System.out.println(")");
//6.异常类型
Class[] exps = m.getExceptionTypes();
if(exps.length != 0){
System.out.print("throws ");
}
for(int i = 0;i < exps.length;i++){
System.out.println(exps[i].getName() + " ");
}
System.out.println();
}
}
//调用运行时类中指定的方法
@Test
public void test3() throws Exception{
Class clazz = MethodDemo.class;
//getMethod(String methodName,Class ... params):获取运行时类中声明为public的指定的方法
Method m1 = clazz.getMethod("test2");
MethodDemo p = (MethodDemo)clazz.newInstance();
//调用指定的方法:Object invoke(Object obj,Object ... obj)
Object returnVal = m1.invoke(p);//我是一个人
//对于运行时类中静态方法的调用
Method m3 = clazz.getMethod("test3");
m3.invoke(MethodDemo.class);
//getDeclaredMethod(String methodName,Class ... params):获取运行时类中声明了的指定的方法
Method m4 = clazz.getDeclaredMethod("test1",String.class,int.class);
m4.setAccessible(true);
Object value = m4.invoke(p,"str",10);//我的国籍是:CHN
System.out.println(value);//10
}
}
class MethodDemo {
@SuppressWarnings(value = { "哈哈哈" })
private int test1(String str, int i) throws NullPointerException{
return i++;
}
public void test2() {
System.out.println("-----test()2 function--");
}
public static void test3() {
System.out.println("-----static test function--");
}
}
Field
Field 类的方法有些和 Method 类的很类似。
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import org.junit.Test;
public class TestField {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
}
@Test public void test1() {
Class clazz = FieldDemo.class;
//getDeclaredFields():获取运行时类本身声明的所有的属性
Field[] field = clazz.getDeclaredFields();
for(Field f : field){
System.out.println("--fieldName--" + f.getName());
//1.获取每个属性的权限修饰符
int i = f.getModifiers();
System.out.println("--Modifier--" + Modifier.toString(i));
//2.获取属性的类型
Class type = f.getType();
System.out.println("--type--" +type.getName() + " ");
System.out.println("-----分割线------");
}
}
@Test public void test2() throws Exception{
Class clazz = FieldDemo.class;
//1.获取指定的属性
//getField(String fieldName):获取运行时类中声明为public的指定属性名为fieldName的属性
Field fieldName = clazz.getField("i");
//2、创建对象
FieldDemo fd = (FieldDemo)clazz.newInstance();
//3.为运行时类的指定的属性赋值
fieldName.set(fd, 10);
System.out.println(fd.i);
//获取非public 方法
//getDeclaredField(String fieldName):获取运行时类中指定的名为fieldName的属性
Field fieldName1 = clazz.getDeclaredField("str");
fieldName1.setAccessible(true);
fieldName1.set(fd, "i like you");
System.out.println(fd.getStr());
}
}
class FieldDemo {
public int i;
private String str;
public String getStr() {
return this.str;
}
}