在运行状态中,对于任意一个实体类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
主要提供了以下功能:
反射的重点在于运行时阶段,可以动态加载和获取。常见的应用场合:
优点:
提升程序的灵活性和扩展性
缺点:
破坏代码的封装性和可读性
性能差。反射相当于一系列解释操作,通知jvm要做的事情,性能比直接的java代码要慢很多。
java.lang.Class; //类
java.lang.reflect.Constructor;//构造方法
java.lang.reflect.Field; //类的成员变量
java.lang.reflect.Method;//类的方法
java.lang.reflect.Modifier;//访问权限
/**
* 方式一:调用某个对象的getClass()方法
*/
User p=new User();
Class clazz=user.getClass();
/**
* 方式二:调用某个类的class属性来获取该类对应的Class对象
*/
Class clazz=User.class;
/**
* 使用反射:使用Class类中的forName()静态方法;
*/
Class clazz=Class.forName("com.lin.app.test.User");
//是否是基础类型
boolean isPrimitive = class1.isPrimitive();
//是否是集合类
boolean isArray = class1.isArray();
//是否是注解类
boolean isAnnotation = class1.isAnnotation();
//是否是接口类
boolean isInterface = class1.isInterface();
//是否是枚举类
boolean isEnum = class1.isEnum();
//是否是匿名内部类
boolean isAnonymousClass = class1.isAnonymousClass();
//是否被某个注解类修饰
boolean isAnnotationPresent = class1.isAnnotationPresent(Deprecated.class);
//获取class名字 包含包名路径
String className = class1.getName();
//获取class的包信息
Package aPackage = class1.getPackage();
//获取class类名
String simpleName = class1.getSimpleName();
//获取class访问权限
int modifiers = class1.getModifiers();
//内部类
Class>[] declaredClasses = class1.getDeclaredClasses();
//外部类
Class> declaringClass = class1.getDeclaringClass();
/**
* 方式一:使用默认构造函数创建
* 调用Class.newInstance()
* 或通过Constructor.newInstance
*/
try {
Class clazz = User.class;
User user = (User) clazz.newInstance();
Constructor constructor = clazz.getConstructor();
User user1 = (User) constructor.newInstance();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
/**
* 方式二:使用带参构造函数创建
* 调用Constructor.newInstance
*/
try {
Class clazz = User.class;
Constructor constructor = clazz.getDeclaredConstructor(String.class, String.class);
User user = (User) constructor.newInstance("", "");
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
/**
* Class:
* Field getField(String name) 获得类声明的指定公共字段(无法获取Private字段)
* Field[] getFields() 获得类声明的所有公共字段(无法获取Private字段)
* Field getDeclaredField(String name) 获取类声明的指定字段
* Field[] getDeclaredFields() 获取类声明的所有字段
*
* Field:
* getType() 返回这个变量的类型
* getGenericType() 如果当前属性有签名属性类型就返回,否则就返回 Field.getType()
* isEnumConstant() 判断这个属性是否是枚举类
* getModifiers() 获取语言修饰符 public、private等
* getName() 获取属性的名字
* get(Object obj) 获取该对象属性值
* set(Object obj, Object value) 设置该对象属性值
* setAccessible(boolean flag) 设置允许访问private对象
*/
/**
* Class:
* getMethods(); 获取类声明的公共方法(无法获取Private方法)
* getMethod(String name, Class>... parameterTypes) 获取类声明的指定公共方法(无法获取Private方法)
* getDeclaredMethods(); 获取类声明的所有方法
* getDeclaredMethod(String name, Class>... parameterTypes) 获取类声明的指定方法
*
* Method:
* getDeclaringClass() 返回方法所在的Class
* getParameterTypes() 形参类型
* getExceptionTypes() 抛出的异常类型
* getReturnType() 返回类型
* getModifiers() 获取语言修饰符 public、private等
* getName() 获取方法名称
* setAccessible(boolean flag) 设置允许访问private对象
* isBridge() 是否是桥接方法
* isSynthetic() 是否是复合方法
* isVarArgs() 是否带有可变参数
* invoke(Object obj, Object... args)调用方法
* getAnnotation(Class annotationClass) 获取注解信息
*/
public class Test {
public void getClazz() {
//方式一:使用默认构造函数创建
try {
Class clazz = User.class;
User user = (User) clazz.newInstance();
Constructor constructor = clazz.getConstructor();
User user1 = (User) constructor.newInstance();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
//方式二:通过Constructor.newInstance创建
try {
Class clazz = User.class;
Constructor constructor = clazz.getDeclaredConstructor(String.class, String.class);
User user = (User) constructor.newInstance("", "");
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
try {
Class clazz = Class.forName("com.lin.app.test.User");
Object obj = clazz.getDeclaredConstructor(String.class, String.class).newInstance("姓名", "地址");
Field address = clazz.getDeclaredField("address");
//设置允许访问private对象
address.setAccessible(true);
//获取address的值
print("before ", address.getName(), address.get(obj).toString());
//改变address的值
address.set(obj, "成都");
print("after ", address.getName(), address.get(obj).toString());
Method setMethod=clazz.getDeclaredMethod("setName",String.class);
//设置允许访问private对象
setMethod.setAccessible(true);
Method getMethod=clazz.getDeclaredMethod("getName",String.class);
getMethod.setAccessible(true);
print("before",getMethod.getName(),((String)getMethod.invoke(obj)));
setMethod.invoke(obj,"张三");
print("after",getMethod.getName(),((String)getMethod.invoke(obj)));
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
private void print(String... msg) {
StringBuilder builder = new StringBuilder();
for (String s : msg) {
builder.append(s).append(" - ");
}
if (builder.length() > 0) {
builder.deleteCharAt(builder.length() - 2);
}
Log.e(getClass().getSimpleName(), builder.toString());
}
}
public class User {
private String name;
private String address;
public User() {
}
public User(String name, String address) {
this.name = name;
this.address = address;
}
private String getName() {
return name;
}
private void setName(String name) {
this.name = name;
}
}