java 反射基础
1. 什么是反射?
主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。本质就是在运行时识别对象和类的信息。
2. 为什么需要反射?
通过反射,我们能够
- 在运行时检测对象的类型;
- 动态构造某个类的对象;
- 检测类的属性和方法;
- 任意调用对象的方法;
- 修改构造函数、方法、属性的可见性
3. Class对象
3.1 获取方式
想在运行时使用类型信息,必须获取对象Class对象的引用,获取Class有三种方式
1. Class clazz = Class.forName("类全限定名");
2. Class clazz = 类名.class;
3. Class clazz = 对象.getClass();
3.2 常用方法
获取类信息 | 方法签名 |
---|---|
获取包名 | Package getPackage() |
获取修饰符 | int getModifiers() |
获取类简名 | String getSimpleName() |
获取类全限定名 | String getName() |
获取该类的类加载器 | ClassLoader getClassLoader() |
返回直接实现的接口(由于编译擦除,没有显示泛型参数) | Class[] getInterfaces() |
返回直接继承的父类(由于编译擦除,没有显示泛型参数) | ClassgetSuperclass() |
返回直接实现的接口(包含泛型参数) | Type[] getGenericInterfaces() |
返回直接继承的父类(包含泛型参数) | Type getGenericSuperclass() |
获取public构造方法 | Constructor getConstructor(Class… parameterTypes) |
获取所有public构造方法 | Constructor[] getConstructors() |
获取public的方法 | Method getMethod(String name, Class… parameterTypes) |
获取所有public的方法,包括父类 | Method[] getMethods() |
获取public的属性 | Field getField(String name) |
取所有public的属性 | Field[] getFields() |
获取声明的构造方法 | Constructor getDeclaredConstructor(Class… parameterTypes) |
获取所有声明的构造方法 | Constructor[] getDeclaredConstructors() |
获取声明的方法 | Method getDeclaredMethod(String name, Class… parameterTypes) |
获取所有声明的方法 | Method[] getDeclaredMethods() |
获取声明的属性 | Field getDeclaredField(String name) |
获取所有声明的属性 | Field[] getDeclaredFields() |
3.3 父类 & 接口 信息
- 不包含范型:
public static void main(String[] args) throws Exception {
Class clazz = Class.forName("java.util.LinkedList");
System.out.println(clazz.getSuperclass());
System.out.println("----------------");
Class[] classes = clazz.getInterfaces();
for(Class c : classes){
System.out.println(c);
}
}
输出:
class java.util.AbstractSequentialList
----------------
interface java.util.List
interface java.util.Deque
interface java.lang.Cloneable
interface java.io.Serializable
- 包含范型:
public static void main(String[] args) throws Exception {
Class clazz = Class.forName("java.util.LinkedList");
System.out.println(clazz.getGenericSuperclass());
System.out.println("----------------");
Type[] types = clazz.getGenericInterfaces();
for (Type type : types) {
System.out.println(type);
}
}
输出:
java.util.AbstractSequentialList<E>
----------------
java.util.List<E>
java.util.Deque<E>
interface java.lang.Cloneable
interface java.io.Serializable
3.4 Declared vs NonDeclared
- 带有Declared的方法,都是获取Class类中声明的方法或者属性
不带Declared的方法,都是获取Class类的public方法或者属性,包括继承自父类的方法或者属性
- 构造方法:
public static void main(String[] args) throws Exception {
Class clazz = Class.forName("com.lilongjiu.study.reflection.Student");
//获取public 构造方法
Constructor[] constructors = clazz.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
System.out.println("----------------------");
//获取所有构造方法
Constructor[] constructors1 = clazz.getDeclaredConstructors();
for (Constructor constructor : constructors1) {
System.out.println(constructor);
}
}
输出:
public com.lilongjiu.study.reflection.Student(java.lang.String,java.lang.String)
----------------------
public com.lilongjiu.study.reflection.Student(java.lang.String,java.lang.String)
private com.lilongjiu.study.reflection.Student(java.lang.String)
- 方法:
public static void main(String[] args) throws Exception {
Class clazz = Class.forName("com.lilongjiu.study.reflection.Student");
//获取public方法,包括父类
Method[] methods = clazz.getMethods();
for (Method method : methods) {
System.out.println(method);
}
System.out.println("----------------------");
//获取所有方法,当前类声明的所有方法
Method[] methods2 = clazz.getDeclaredMethods();
for (Method method : methods2) {
System.out.println(method);
}
}
输出:
public void com.lilongjiu.study.reflection.Student.attendClass()
public java.lang.String com.lilongjiu.study.reflection.People.toString()
public java.lang.String com.lilongjiu.study.reflection.People.getName()
public void com.lilongjiu.study.reflection.People.sleep()
public void com.lilongjiu.study.reflection.People.setName(java.lang.String)
public java.lang.String com.lilongjiu.study.reflection.People.getId()
public void com.lilongjiu.study.reflection.People.eat(java.lang.String)
public void com.lilongjiu.study.reflection.People.setId(java.lang.String)
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 final void java.lang.Object.wait() throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
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()
----------------------
public void com.lilongjiu.study.reflection.Student.attendClass()
private void com.lilongjiu.study.reflection.Student.playGame()
3.3 类基本信息
public static void main(String[] args) throws Exception {
Class clazz = Class.forName("com.lilongjiu.study.reflection.People");
//获取包名
System.out.println(clazz.getPackage());
//获取修饰符
System.out.println(clazz.getModifiers());
//获取类简名
System.out.println(clazz.getSimpleName());
//获取类全限定名
System.out.println(clazz.getName());
//获取该类的类加载器
System.out.println(clazz.getClassLoader());
}
输出:
package com.lilongjiu.study.reflection
1
People
com.lilongjiu.study.reflection.People
sun.misc.Launcher$AppClassLoader@1ddc4ec2
4. reflect 包
在java.lang.reflect包中有三个重要的类,这三个类分别表示:构造器,方法,属性。
- Constructor
- Method
- Field
- Modifier
5. Constructor
5.1 无参构造方法 & 实例化
- 类有无参的构造方法
- Class.newInstance()
- Constructor.newInstance()
public static void main(String[] args) throws Exception {
Class clazz = Class.forName("com.lilongjiu.study.reflection.People");
//Class.newInstance()
People p1 = (People) clazz.newInstance();
//Constructor.newInstance()
Constructor constructor = clazz.getConstructor(null);
People p2 = (People) constructor.newInstance();
System.out.println(p1);
System.out.println(p2);
}
输出:
People{id='null', name='null'}
People{id='null', name='null'}
5.1 带参数的构造方法 & 实例化
public static void main(String[] args) throws Exception {
Class clazz = Class.forName("com.lilongjiu.study.reflection.People");
Constructor constructor = clazz.getConstructor(new Class[]{String.class, String.class});
People people = (People) constructor.newInstance("123", "zhangsan");
System.out.println(people);
}
输出:
People{id='123', name='zhangsan'}
5.2 私有构造方法 & 实例化
访问私有方法一定要设置访问权限
- Constructor.setAccessible(boolean flag)
public static void main(String[] args) throws Exception {
Class clazz = Class.forName("com.lilongjiu.study.reflection.People");
Constructor constructor = clazz.getDeclaredConstructor(new Class[]{String.class});
constructor.setAccessible(true);
People people = (People) constructor.newInstance("zhangsan");
System.out.println(people);
}
输出:
People{id='null', name='zhangsan'}
6. Method
6.1 无参方法 & 调用
public static void main(String[] args) throws Exception {
Class clazz = Class.forName("com.lilongjiu.study.reflection.People");
Constructor constructor = clazz.getDeclaredConstructor(new Class[]{String.class, String.class});
People people = (People) constructor.newInstance("123", "zhangsan");
Method method = clazz.getMethod("sleep", null);
method.invoke(people,null);
}
输出:
zhangsan is sleeping
6.2 带参方法 & 调用
public static void main(String[] args) throws Exception {
Class clazz = Class.forName("com.lilongjiu.study.reflection.People");
Constructor constructor = clazz.getDeclaredConstructor(new Class[]{String.class, String.class});
People people = (People) constructor.newInstance("123", "zhangsan");
Method method = clazz.getMethod("eat", new Class[] {String.class});
method.invoke(people,"Apple");
}
输出:
zhangsan is eating Apple
6.3 私有方法 & 调用
- method.setAccessible(true);
public static void main(String[] args) throws Exception {
Class clazz = Class.forName("com.lilongjiu.study.reflection.People");
Constructor constructor = clazz.getDeclaredConstructor(new Class[]{String.class, String.class});
People people = (People) constructor.newInstance("123", "zhangsan");
Method method = clazz.getDeclaredMethod("study", new Class[] {String.class});
method.setAccessible(true);
method.invoke(people,"Java Reflection");
}
输出:
zhangsan is studying Java Reflection
7. Field
7.1 类的字段
public static void main(String[] args) throws Exception {
Class clazz = Class.forName("com.lilongjiu.study.reflection.People");
Constructor constructor = clazz.getDeclaredConstructor(new Class[]{String.class, String.class});
People people = (People) constructor.newInstance("123", "zhangsan");
Field field = clazz.getDeclaredField("name");
field.setAccessible(true);
//输出对象对应的属性值
System.out.println(field.get(people));
//输出属性类型
System.out.println(field.getType());
}
输出:
zhangsan
class java.lang.String
8. Modifier
- Class, Method, Field 都有 getModifiers 方法,其返回值是一个整数,Modifier可以根据这个整数判断对应的修饰符。
public static void main(String[] args) throws Exception {
Class clazz = Class.forName("java.util.List");
Method method = clazz.getDeclaredMethod("add", new Class[]{Object.class});
int modifiers = method.getModifiers();
System.out.println(modifiers);
System.out.println(Modifier.isPublic(modifiers));
System.out.println(Modifier.isAbstract(modifiers));
System.out.println(Modifier.isVolatile(modifiers));
System.out.println(Modifier.isStatic(modifiers));
System.out.println(Modifier.isFinal(modifiers));
}
输出:
1025
true
true
false
false
false
- Modifier 定义了一些静态属性来表示public,abstract,static,final等修饰符
//非完整Modifer类
public class Modifier {
public static final int PUBLIC = 1;
public static final int PRIVATE = 2;
public static final int PROTECTED = 4;
public static final int STATIC = 8;
public static final int FINAL = 16;
public static final int SYNCHRONIZED = 32;
public static final int VOLATILE = 64;
public static final int TRANSIENT = 128;
public static final int NATIVE = 256;
public static final int INTERFACE = 512;
public static final int ABSTRACT = 1024;
public static final int STRICT = 2048;
static final int BRIDGE = 64;
static final int VARARGS = 128;
static final int SYNTHETIC = 4096;
static final int ANNOTATION = 8192;
static final int ENUM = 16384;
static final int MANDATED = 32768;
private static final int CLASS_MODIFIERS = 3103;
private static final int INTERFACE_MODIFIERS = 3087;
private static final int CONSTRUCTOR_MODIFIERS = 7;
private static final int METHOD_MODIFIERS = 3391;
private static final int FIELD_MODIFIERS = 223;
private static final int PARAMETER_MODIFIERS = 16;
static final int ACCESS_MODIFIERS = 7;
public Modifier() {
}
public static boolean isPublic(int var0) {
return (var0 & 1) != 0;
}
public static boolean isPrivate(int var0) {
return (var0 & 2) != 0;
}
public static boolean isProtected(int var0) {
return (var0 & 4) != 0;
}
public static boolean isStatic(int var0) {
return (var0 & 8) != 0;
}
public static boolean isFinal(int var0) {
return (var0 & 16) != 0;
}
public static boolean isSynchronized(int var0) {
return (var0 & 32) != 0;
}
public static boolean isVolatile(int var0) {
return (var0 & 64) != 0;
}
public static boolean isTransient(int var0) {
return (var0 & 128) != 0;
}
public static boolean isNative(int var0) {
return (var0 & 256) != 0;
}
public static boolean isInterface(int var0) {
return (var0 & 512) != 0;
}
public static boolean isAbstract(int var0) {
return (var0 & 1024) != 0;
}
public static boolean isStrict(int var0) {
return (var0 & 2048) != 0;
}
...
}
9. Code
People类源码
package com.lilongjiu.study.reflection;
/**
* Created by lilongjiu.
*/
public class People {
private String id;
private String name;
public People() {
}
public People(String id, String name) {
this.id = id;
this.name = name;
}
private People(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void eat(String food) {
System.out.println(this.getName() + " is eating " + food);
}
private void study(String course) {
System.out.println(this.getName() + " is studying " + course);
}
public void sleep() {
System.out.println(this.getName() + " is sleeping");
}
@Override
public String toString() {
return "People{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
'}';
}
}
package com.lilongjiu.study.reflection;
/**
* Created by lilongjiu.
*/
public class Student extends People{
public String school;
private String major;
public Student(String id, String name){
super(id, name);
}
private Student(String name){
super(null, name);
}
public void attendClass(){
System.out.println(this.getName() + " is atending class");
}
private void playGame(){
System.out.println(this.getName() + " is playing game");
}
}