介绍
- 反射是啥?首先,百度百科是这么说:Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。
它的意思就是把java类中的各种成分封装、映射成一个个的Java对象。例如:一个类有:成员变量、方法、构造方法、注解等等信息,对应封装成Field、Method、Constructor、Annotation,可以对一个类进行解剖,把个个组成部分映射成一个个对象。当你想调用某个对象的方法时,也可以通过反射的Method类调用的。理论的东西不理解不要紧,通过API多实操慢慢就理解了。
常用简单API
这里有个People类:
package reflect;
@SuppressWarnings("")
public class People {
private String name;
private int age;
public String nickName;
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 People(String name, int age) {
this.name = name;
this.age = age;
}
public People() {
}
private People(String name) {
this.name = name;
}
private String name() {
return name;
}
@Override
public String toString() {
return "People{" +
"name='" + name + '\'' +
", age=" + age +
", nickName='" + nickName + '\'' +
'}';
}
}
- 获取 Class 对象的四种方式。
Class clz = People.class;
Class clz1 = Class.forName(“reflect.People”);
People p = new People();
Class clz2 = p.getClass();
Class clz3 = ClassLoader.LoadClass(“reflect.People”); //忽略 - 简单看看Class、Field 、Method的使用。
java.lang.Class 类的模子
java.lang.reflect.Constructor 类的构造方法
java.lang.reflect.Field 类的成员变量,可以用来获取和设置类之中的属性值等
java.lang.reflect.Method 类的方法,可以执行指定方法
java.lang.reflect.Modifier 类的访问权限
下面演示Class、Field 、Method一些API 。
public class ReflectTest {
public static void main(String[] args) throws Exception {
//Class、Field 、Method
Class clz = Class.forName("reflect.People");
//获取所有公共构造方法
Constructor[] conArray = clz.getConstructors();
//所有的构造方法(包括:私有、受保护、默认、公有)
conArray = clz.getDeclaredConstructors();
//获取私有 有参的构造方法
Constructor declaredConstructor = clz.getDeclaredConstructor(String.class);
//获取公共 有参的构造方法
Constructor constructor = clz.getConstructor(String.class, int.class);
//创建对应的实例
Object newInstance = constructor.newInstance("隔壁老王", 18);
//People{name='隔壁老王', age=18, nickName='null'}
System.out.println(newInstance);
//获取类上 指定注解
final Annotation annotation = clz.getAnnotation(SuppressWarnings.class);
System.out.println(annotation);
//返回此类上 存在的注解
Annotation[] annotations = clz.getAnnotations();
//获取指定公共字段
Field nickName = clz.getField("nickName");
//获取指定私有字段
Field name = clz.getDeclaredField("name");
//获取所有字段 包括私有
Field[] declaredFields = clz.getDeclaredFields();
//获取所有公共字段
Field[] fields = clz.getFields();
//获取指定方法
Method declaredMethod = clz.getDeclaredMethod("name");
//private java.lang.String reflect.People.name()
System.out.println(declaredMethod.toString());
//获取所有方法
Method[] declaredMethods = clz.getDeclaredMethods();
//获取所有公共方法
Method[] methods = clz.getMethods();
//获取指定公共方法
Method method = clz.getMethod("getName");
//public java.lang.String reflect.People.getName()
System.out.println(method.toString());
String packageName = clz.getPackageName();
System.out.println(packageName);
//People 也就类名
String simpleName = clz.getSimpleName();
System.out.println(simpleName);
//此类是否数组
boolean array = clz.isArray();
//是否接口
boolean anInterface = clz.isInterface();
//是否表示基本类型
boolean primitive = clz.isPrimitive();
//----------------------------------------------------------------------------------------------
Field name1 = clz.getDeclaredField("name");
//将私有字段设置可以访问
name1.setAccessible(true);
//拿到newInstance对象name字段的值
Object o = name1.get(newInstance);
//隔壁老王
System.out.println(o);
//赋值此私有字段
name1.set(newInstance, "隔壁lsp");
// 隔壁lsp
Object o1 = name1.get(newInstance);
System.out.println(o1);
//拿到此字段上的注释
Deprecated annotation1 = name1.getAnnotation(Deprecated.class);
//以整数形式返回此字段对象表示的字段的Java语言修饰符(组合的话就数值相加,什么数值代表什么看结尾的表格)
int modifiers = name1.getModifiers();
//2
System.out.println(modifiers);
//----------------------------------------------------------------------------------------------
Method method1 = clz.getDeclaredMethod("name");
//将私有方法设置可以访问,公共的话就不用了
method1.setAccessible(true);
//执行转入对象的对应方法
Object invoke = method1.invoke(newInstance);
//打印返回值 隔壁lsp
System.out.println(invoke);
}
}
modifiers :
修饰符 | Value |
---|---|
public | 1 |
private | 2 |
protected | 4 |
static | 8 |
final | 16 |
synchronized | 32 |
volatile | 64 |
transient | 128 |
native | 256 |
interface | 512 |
abstract | 1024 |
strict | 2048 |
动动你性感的小手指斜体样式*,帮我点点赞吧(づ ̄3 ̄)づ╭❤~*