Java反射的使用
Java反射的使用
生活就像海洋,只有意志坚强的人,才能到达彼岸。
获取包名 类名
clazz.getPackage().getName()//包名
clazz.getSimpleName()//类名
clazz.getName()//完整类名
获取成员变量定义信息
getFields()//获取所有公开的成员变量,包括继承变量
getDeclaredFields()//获取本类定义的成员变量,包括私有,但不包括继承的变量
getField(变量名)
getDeclaredField(变量名)
获取构造方法定义信息
getConstructor(参数类型列表)//获取公开的构造方法
getConstructors()//获取所有的公开的构造方法
getDeclaredConstructors()//获取所有的构造方法,包括私有
getDeclaredConstructor(int.class,String.class)
获取方法定义信息
getMethods()//获取所有可见的方法,包括继承的方法
getMethod(方法名,参数类型列表)
getDeclaredMethods()//获取本类定义的的方法,包括私有,不包括继承的方法
getDeclaredMethod(方法名,int.class,String.class)
反射新建实例
clazz.newInstance();//执行无参构造创建对象
clazz.newInstance(666,”海绵宝宝”);//执行含参构造创建对象
clazz.getConstructor(int.class,String.class)//获取构造方法
反射调用成员变量
clazz.getDeclaredField(变量名);//获取变量
clazz.setAccessible(true);//使私有成员允许访问
f.set(实例,值);//为指定实例的变量赋值,静态变量,第一参数给null
f.get(实例);//访问指定实例变量的值,静态变量,第一参数给null
反射调用成员方法
Method m = Clazz.getDeclaredMethod(方法名,参数类型列表);
m.setAccessible(true);//使私有方法允许被调用
m.invoke(实例,参数数据);//让指定实例来执行该方法
测试反射的使用
测试类:
package com.cnblogs.reflection;
import org.junit.Test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
/*
测试反射
*/
public class TestReflection {
public static void main(String[] args) throws ClassNotFoundException {
//获取字节码对象
Class clazz1 = Student.class;
Class clazz2 = new Student().getClass();
Class clazz3 = Class.forName("com.cnblogs.reflection.Student");
System.out.println(clazz1);
System.out.println(clazz2);
System.out.println(clazz3);
//class com.cnblogs.reflection.Student
System.out.println(clazz1.getName());//com.cnblogs.reflection.Student
System.out.println(clazz1.getSimpleName());//Student
System.out.println(clazz1.getPackage());//package com.cnblogs.reflection
System.out.println(clazz1.getPackage().getName());//com.cnblogs.reflection
}
//通过单元测试方法测试获取Student类的构造方法
@Test
public void TestGetConstruct(){
//获取字节码文件
Class clazz = Student.class;
//获取构造方法们
Constructor<?>[] constructor = clazz.getConstructors();
System.out.println(constructor);//[Ljava.lang.reflect.Constructor;@573fd745
System.out.println(Arrays.toString(constructor));
//[public com.cnblogs.reflection.Student(), public com.cnblogs.reflection.Student(java.lang.String,int)]
//遍历数组,获取每一个构造方法
for (Constructor<?> x : constructor){
System.out.println(x.getName());//cn.tedu.reflection.Student
Class<?>[] p = x.getParameterTypes();//获取参数类型
System.out.println(Arrays.toString(p));
/*
[]
[class java.lang.String, int]
*/
}
}
//通过单元测试方法测试获取Student类的普通方法
@Test
public void TestGetFunction(){
//获取字节码文件
Class clazz = Student.class;
//获取普通方法
Method[] ms = clazz.getMethods();
System.out.println(ms);//[Ljava.lang.reflect.Method;@621be5d1
System.out.println(Arrays.toString(ms));//[public void cn.tedu.reflection.Student.eat(), public final void java.lang.Object.wait() throws java.lang.InterruptedException, public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException, public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException, public boolean java.lang.Object.equals(java.lang.Object), public java.lang.String java.lang.Object.toString(), public native int java.lang.Object.hashCode(), public final native java.lang.Class java.lang.Object.getClass(), public final native void java.lang.Object.notify(), public final native void java.lang.Object.notifyAll()]
//注意:默认继承了顶级父类Object类的一些方法
for (Method x : ms){
System.out.println(x.getName());
Class<?>[] p = x.getParameterTypes();
System.out.println(Arrays.toString(p));
}
/*
eat
[]
wait
[]
wait
[long, int]
wait
[long]
equals
[class java.lang.Object]
toString
[]
hashCode
[]
getClass
[]
notify
[]
notifyAll
[]
*/
}
//获取成员变量
/*这里成员变量为修饰符public的才能被获取*/
@Test
public void TestGetFields(){//获取的是公共属性
//获取字节码对象
Class<?> clazz = Student.class;
Field[] fs = clazz.getFields();
for(Field x : fs){
System.out.println(x.getName());//获取属性名
System.out.println(x.getType().getName());//获取属性的类型名
}
}
/*
name
java.lang.String
age
int
*/
//通过单元测试方法创建目标对象
@Test
public void TestGetObject() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
Class<?> clazz = Student.class;
//创建对象,触发无参构造来创建目标类对象
Object obj = clazz.newInstance();//多态来接
System.out.println(obj);//cn.tedu.reflection.Student@4ee285c6
/*重写toString后 Student{name='null', age=0}*/
//创建对象,想触发对应的含参构造创建目标对象
Constructor<?> c = clazz.getConstructor(String.class, int.class);
Object obj2 = c.newInstance("海绵宝宝", 5);
System.out.println(obj2);//Student{name='海绵宝宝', age=5}
/*注意:指定构造函数的参数类型时,传入的是字节码对象*/
//查看对象具体的属性值
Student s = (Student)obj2;//多态中,父类不可以直接引用子类的特有属性和特有方法,需要强转为Student
System.out.println(s.name);//海绵宝宝
s.eat();//疯狂干饭!!!
}
}
物料类:
package com.cnblogs.reflection;
/*
物料类,咱假装这是别人写的
*/
public class Student {
public String name;
public int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public void eat(){
System.out.println("疯狂干饭!!!");
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
暴力反射
测试类:
package com.cnblogs.reflection;
import org.junit.Test;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class TestReflection2 {
//暴力反射获取私有属性
@Test
public void getFileds() throws NoSuchFieldException, IllegalAccessException, InstantiationException {
Class<?> clazz = Person.class;
Field filed = clazz.getDeclaredField("name");
//根据获取到的私有属性对象获取对应的信息
System.out.println(filed.getName());//name
System.out.println(filed.getType().getName());//java.lang.String
filed.setAccessible(true);//设置私有资源可见的权限
//给指定的属性设置值
/*set(m,n)
m 要给哪个对象设置属性
n 要设置什么值
*/
//先创建对象
Object obj = clazz.newInstance();
filed.set(obj,"张三");
System.out.println(filed.get(obj));//张三
}
//通过暴力反射获取和使用私有方法
@Test
public void getFunction() throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
Class<?> clazz = Person.class;
/*
getDeclaredMethod(m,x,y,z...)
m 获取的方法的名字
x,y,z 获取方法的参数,注意是字节码对象
*/
Method method = clazz.getDeclaredMethod("find", String.class);
//设置私有可见
method.setAccessible(true);
Object obj = clazz.newInstance();//创建对象
method.invoke(obj,"张三");//通过invoke()使用方法
}
}
物料类:
package com.cnblogs.reflection;
/*
暴力反射的物料类
*/
public class Person {
private String name;
private int age;
private void find(String s){
System.out.println("find..." + s);
}
private void update(){
System.out.println("刷新中...");
}
}