反射的学习总结
2020-08-04 本文已影响0人
132xin
反射的定义
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任何一个对象,都能够调用它的任意方法和属性。这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。在使用反射机制中第一步是获取该类的字节码文件,然后可以获取该类的信息。
获取字节码文件的三种方式
根据类名 :类名.class
根据对象:对象.getClass
根据全限定类名:Class.forName(全限定类名)
//根据类名
Class class1=Person.class;
//更据对象
Person person=new Person("Reflex", 18);
Class class2=person.getClass();
//根据全限定名
try {
Class class3 = Class.forName("Reflex.Person");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
反射的优缺点:
优点:
反射提高了Java程序的灵活性和扩展性,降低耦合性,提高自适应能力。
缺点:
性能问题:使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。
使用反射会模糊程序内部逻辑:程序员希望在源代码中看到程序的逻辑,反射等绕过了 源代码的技术,因而会带来维护问题。反射代码对比相应的直接代码要复杂。
获取信息
获取构造方法
/**
/**
* 获取构造参数
*
* @param class1
*/
public static Person getConstructor(Class class1) {
try {
//获取构造参数,传入的参数决定获取哪个构造方法
Constructor constructor=class1.getConstructor(String.class,int.class);
//进行实例化
Object preson=constructor.newInstance("Reflex",18);
preson.toString();
return (Person) preson;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 获取所有的参数
*/
public static void getConstructors(Class class1) {
Constructor[] constructors=class1.getConstructors();
for(int i=0;i<constructors.length;i++) {
//获取每个构造函数中的参数类型的字节码对象
Class[] parameterTypes=constructors[i].getParameterTypes();
System.out.println("第"+i+"构造参数");
for(int j=0;j<parameterTypes.length;j++) {
System.out.print(parameterTypes[j].getName()+",");
}
}
}
获取属性
//获取属性
public static void getField(Class class1) {
try {
Person person=getConstructor(class1);
//获取成员变量,通过指定name来获取
Field publicField=class1.getField("age");
//获取私有的成员变量
Field declaredFiled=class1.getDeclaredField("name");
//对私有的属性进行操作时,要打开权限
declaredFiled.setAccessible(true);
//复杂等操作
declaredFiled.set(person, "ReflexField");
publicField.set(person, 19);
person.toString();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
//获取全部属性的方法
Field[] fields=class1.getFields();
//获取所有的私有属性
Field[] fields2=class1.getDeclaredFields();
}
获取方法
// 获取方法
public static void getMethod(Class class1) {
try {
Person person=getConstructor(class1);
/**
* classs.getMethod(name,paraMeterTypes)
* name:方法的名称
* paraMeterTypes:方法的参数类型,没有则什么都不填 例如:String.class
*/
Method eatMethod=class1.getMethod("eat", String.class);
//获取私有的方法
// Method privateMethod=class1.getDeclaredMethod(name, parameterTypes)
//打开权限,私有的方法一定要加上打开权限
eatMethod.setAccessible(true);
//调用方法
/*
* method.invoke(obj,args)
* obj:方法的对象
* args:实际的参数值,没有则不填
*/
eatMethod.invoke(person, "猪肉");
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
//获取所有的方法
Method[] methods=class1.getMethods();
//所有私有的方法
Method[] privateMethods=class1.getDeclaredMethods();
}
所有的代码:
public class ReflexTest {
public static void main(String[] args) {
// 根据类名
Class class1 = Person.class;
// 更据对象
Person person = new Person("Reflex", 18);
Class class2 = person.getClass();
// 根据全限定名
try {
Class class3 = Class.forName("Reflex.Person");
} catch (Exception e) {
e.printStackTrace();
}
getConstructor(class1);
getConstructors(class1);
getField(class1);
getMethod(class1);
}
/**
* 获取构造参数
*
* @param class1
*/
public static Person getConstructor(Class class1) {
try {
// 获取构造参数,传入的参数决定获取哪个构造方法
Constructor constructor = class1.getConstructor(String.class, int.class);
// 进行实例化
Object preson = constructor.newInstance("Reflex", 18);
preson.toString();
return (Person) preson;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 获取所有的参数
*/
public static void getConstructors(Class class1) {
Constructor[] constructors = class1.getConstructors();
for (int i = 0; i < constructors.length; i++) {
// 获取每个构造函数中的参数类型的字节码对象
Class[] parameterTypes = constructors[i].getParameterTypes();
System.out.println("第" + i + "构造参数");
for (int j = 0; j < parameterTypes.length; j++) {
System.out.print(parameterTypes[j].getName() + ",");
}
}
}
// 获取属性
public static void getField(Class class1) {
try {
Person person = getConstructor(class1);
// 获取成员变量,通过指定name来获取
Field publicField = class1.getField("age");
// 获取私有的成员变量
Field declaredFiled = class1.getDeclaredField("name");
// 对私有的属性进行操作时,要打开权限
declaredFiled.setAccessible(true);
// 复杂等操作
declaredFiled.set(person, "ReflexField");
publicField.set(person, 19);
person.toString();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
// 获取全部属性的方法
Field[] fields = class1.getFields();
// 获取所有的私有属性
Field[] fields2 = class1.getDeclaredFields();
}
// 获取方法
public static void getMethod(Class class1) {
try {
Person person=getConstructor(class1);
/**
* classs.getMethod(name,paraMeterTypes)
* name:方法的名称
* paraMeterTypes:方法的参数类型,没有则什么都不填 例如:String.class
*/
Method eatMethod=class1.getMethod("eat", String.class);
//获取私有的方法
// Method privateMethod=class1.getDeclaredMethod(name, parameterTypes)
//打开权限,私有的方法一定要加上打开权限
eatMethod.setAccessible(true);
//调用方法
/*
* method.invoke(obj,args)
* obj:方法的对象
* args:实际的参数值,没有则不填
*/
eatMethod.invoke(person, "猪肉");
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
//获取所有的方法
Method[] methods=class1.getMethods();
//所有私有的方法
Method[] privateMethods=class1.getDeclaredMethods();
}
}
class Person {
private String name;
public int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person(String name) {
this.name = name;
}
public Person() {
}
public void eat(String food) {
System.out.println("正在吃" + food);
}
@Override
public String toString() {
String string = "Person " + name + " " + age;
System.out.println(string);
return string;
}
}