一.概念
反射机制是在运行状态中:
1.对应任意一个类,都能够知道这个类的所有属性和方法。
2.对于任意一个对象,都能够调用它的任意一个方法和属性。
二.功能
1.在运行时判断一个对象所属的类。
2.在运行时构造任意一个类的对象。
3.在运行时判断任意一个类所具有的成员变量和方法。
4.在运行时调用任意一个对象的方法。
5.生产动态代理
三.实例
Person类:
package reflect;
public class Person implements MyInterface,MyInterface2{
private int id;
private String name;
private int age;
public String desc;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
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 Person(int id) {
this.id = id;
}
public Person(int id,String name,int age) {
this.id = id;
this.name = name;
this.age = age;
}
public Person()
{
}
public static void staticMethod() {
System.out.println("staticMethod");
}
private void privateMethod() {
System.out.println("privateMethod");
}
private void privateMethod2(String name) {
System.out.println("privateMethod2");
}
@Override
public void interfaceMethod() {
System.out.println("interfaceMethod");
}
@Override
public void interface2Method() {
System.out.println("interfaceMethod2");
}
}
myInterface接口:
package reflect;
public interface MyInterface {
void interfaceMethod();
}
myInterface2接口:
package reflect;
public interface MyInterface2 {
void interface2Method();
}
PropertyUtil类:
package reflect;
import java.lang.reflect.Field;
public class PropertyUtil {
public static void setProperty(Object obj,String propertyName,Object value) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
Class<?> class1 = obj.getClass();
Field field = class1.getDeclaredField(propertyName);
field.setAccessible(true);
field.set(obj,value);
}
}
1.通过反射获取类
获取反射对象(入口)有三种方法:
1.Class.forName(“全类名”) 推荐
2.类名.Class
3.对象.getClass()
public static void Demo01() {
//1.Class.forName("全类名")
try {
Class<?> perClass = Class.forName("reflect.Person");
System.out.println(perClass);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//2.类名.Class
Class<?> perClass2 = Person.class;
System.out.println(perClass2);
//3.对象.getClass()
Person per = new Person();
Class<?> perClass3 = per.getClass();
System.out.println(perClass3);
}
2.获取对象方法
1.获取所有公共方法
2.获取当前对象的所有方法
public static void Demo02() {
Class<?> perClass1 = null;
//获取入口
try {
perClass1 = Class.forName("reflect.Person");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//获取所有公共方法
/*
* 1.获取的是本类及父类、接口中的所有方法。
* 2.被符合访问修饰符所限制
*/
**Method[] methods = perClass1.getMethods();**
for(Method method:methods) {
System.out.println(method);
}
System.out.println("-----------");
//获取当前类的所有方法
/*
* 1.当前类
* 2.忽略访问修饰符限制
*/
**Method[] declaredMethods = perClass1.getDeclaredMethods();**
for(Method Dec:declaredMethods) {
System.out.println(Dec);
}
}
3.获取所有接口
public static void Demo03() {
Class<?> perClass1 = null;
//获取入口
try {
perClass1 = Class.forName("reflect.Person");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
**Class<?>[] interfaces = perClass1.getInterfaces();**
for(Class<?> inter: interfaces) {
System.out.println(inter);
}
}
4.获取所有的父类
public static void Demo04() {
Class<?> perClass1 = null;
//获取入口
try {
perClass1 = Class.forName("reflect.Person");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//单继承,所以只有一个父类
**Class<?> superclass = perClass1.getSuperclass();**
System.out.println(superclass);
}
5.获取所有的构造方法
public static void Demo05() {
Class<?> perClass1 = null;
//获取入口
try {
perClass1 = Class.forName("reflect.Person");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
**Constructor<?>[] cons = perClass1.getConstructors();**
for(Constructor<?> con:cons) {
System.out.println(con);
}
}
6.获取属性
1.获取所有的公共属性
2.获取当前类所有的属性
public static void Demo06() {
Class<?> perClass1 = null;
//获取入口
try {
perClass1 = Class.forName("reflect.Person");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//获取公共属性
Field[] field = perClass1.getFields();
for(Field fie:field) {
System.out.println(fie);
}
System.out.println("-----------");
//获取当前类所有的属性(忽略访问修饰符)
Field[] declaredFields = perClass1.getDeclaredFields();
for(Field Dec:declaredFields) {
System.out.println(Dec);
}
}
7.获取当前反射所代表的类(接口)的对象(实例)
public static void Demo07() {
Class<?> perClass1 = null;
//获取入口
try {
perClass1 = Class.forName("reflect.Person");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Object instance = null;
try {
instance = perClass1.newInstance();//获取对象
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
Person per = (Person)instance;//转换为Person
per.interface2Method();//调用方法
}
8.修改对象的公共属性
public static void Demo01() {
Class<?> perClass = null;
//获取入口
try {
perClass = Class.forName("reflect.Person");//获取类
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Person per = null;
try {
per = (Person)perClass.newInstance();//获取到对象的实例
per.setName("张三");//修改姓名
per.setAge(18);//修改年龄
System.out.println(per.getName()+":"+per.getAge());
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
9.修改对象的私有属性
public static void Demo02() throws NoSuchMethodException, IllegalArgumentException, InvocationTargetException {
Class<?> perClass = null;
//获取入口
try {
perClass = Class.forName("reflect.Person");//获取类
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Person per = null;
try {
per = (Person)perClass.newInstance();//获取对象
try {
//id是private
Field idField = perClass.getDeclaredField("id");.//获得私有属性id
idField.setAccessible(true);//忽略访问修饰符
idField.set(per,1);//将id赋值成1
System.out.println(per.getId());
System.out.println("------同理:修改方法访问权限---------");
Method method = perClass.getDeclaredMethod("privateMethod",null);
method.setAccessible(true);
method.invoke(per,null);//无参数
Method method2 = perClass.getDeclaredMethod("privateMethod2",String.class);
method2.setAccessible(true);
method2.invoke(per,"张三");
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
10.获取构造方法
public static void Demo03() throws NoSuchMethodException, SecurityException {
Class<?> perClass = null;
//获取入口
try {
perClass = Class.forName("reflect.Person");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//取公共构造方法
// Constructor<?>[] cons= perClass.getConstructors();
//取本类全部构造方法
// Constructor<?>[] cons= perClass.getDeclaredConstructors();
//获取指定的构造方法
Constructor<?> cons = perClass.getConstructor(int.class);
System.out.println(cons);
}
11.获取文件中指定的对象和方法
public static void Demo04() throws FileNotFoundException, IOException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
Properties prop = new Properties();
prop.load(new FileReader("class.text"));//加载文件
String classname = prop.getProperty("classname");
String methodname = prop.getProperty("methodname");
Class<?> perclass = null;
perclass = Class.forName(classname);//通过类名拿到反射入口
Method method = perclass.getMethod(methodname);
method.invoke(perclass.newInstance());
}
12.越过泛型检查
//反射可以越过泛型检查
public static void Demo05() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException
{
ArrayList<Integer> list = new ArrayList<>();
list.add(123);
list.add(3);
Class<?> listclass = list.getClass();
Method method = listclass.getMethod("add", Object.class);//更改为任意类型
method.invoke(list,"张三");
System.out.println(list);
}
13.代替set给指定的对象中的属性赋值
public static void Demo06() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
Person per = new Person();
PropertyUtil.setProperty(per,"name","张三");
PropertyUtil.setProperty(per, "age", 18);
System.out.println(per.getName()+":"+per.getAge());
}