什么是java的反射机制
java反射机制是在运行状态中,对任意一个类,都能够知道这个类的所有属性和方法;对任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能成为java语言的反射机制
java的反射机制的作用
用来编写一些通用性较高的代码或者框架的时候使用,在日常的第三方应用开发过程中,经常会遇到某个类的某个成员变量、方法或是属性是私有的或是只对系统应用开放,这时候就可以利用Java的反射机制通过反射来获取所需的私有成员或是方法,起到一定的保护用户隐私目的
Class类(代表类的实体,在运行的Java应用程序中表示类和接口)
1.java中java.lang.Class类用于表示一个类的字节码(.class)文件
2.如何得到某个class文件对应的Class对象
--已知类和对象的情况下
类名.class
对象.getClass()------Object类提供
--未知类和对象的情况下
class.forName("包名.类名")
3.Class类代表某个类的字节码,提供了加载字节码 的方法:forName("包名.类名")
--forName方法用于加载类字节码到内存中,并封装成一个Class对象
- 获得类相关的方法
方法 | 用途 |
---|---|
asSubclass(Class<U> clazz) | 把传递的类的对象转换成代表其子类的对象 |
Cast | 把对象转换成代表类或是接口的对象 |
getClassLoader() | 获得类的加载器 |
getClasses() | 返回一个数组,数组中包含该类中所有公共类和接口类的对象 |
getDeclaredClasses() | 返回一个数组,数组中包含该类中所有类和接口类的对象 |
forName(String className) | 根据类名返回类的对象 |
getName() | 获得类的完整路径名字 |
newInstance() | 创建类的实例 |
getPackage() | 获得类的包 |
getSimpleName() | 获得类的名字 |
getSuperclass() | 获得当前类继承的父类的名字 |
getInterfaces() | 获得当前类实现的类或是接口 |
- 获得类中属性相关的方法
方法 | 用途 |
---|---|
getField(String name) | 获得某个公有的属性对象 |
getFields() | 获得所有公有的属性对象 |
getDeclaredField(String name) | 获得某个属性对象 |
getDeclaredFields() | 获得所有属性对象 |
- 获得类中注解相关的方法
方法 | 用途 |
---|---|
getAnnotation(Class<A> annotationClass) | 返回该类中与参数类型匹配的公有注解对象 |
getAnnotations() | 返回该类所有的公有注解对象 |
getDeclaredAnnotation(Class<A> annotationClass) | 返回该类中与参数类型匹配的所有注解对象 |
getDeclaredAnnotations() | 返回该类所有的注解对象 |
- 获得类中构造器相关的方法
方法 | 用途 |
---|---|
getConstructor(Class...<?> parameterTypes) | 获得该类中与参数类型匹配的公有构造方法 |
getConstructors() | 获得该类的所有公有构造方法 |
getDeclaredConstructor(Class...<?> parameterTypes) | 获得该类中与参数类型匹配的构造方法 |
getDeclaredConstructors() | 获得该类所有构造方法 |
- 获得类中方法相关的方法
方法 | 用途 |
---|---|
getMethod(String name, Class...<?> parameterTypes) | 获得该类某个公有的方法 |
getMethods() | 获得该类所有公有的方法 |
getDeclaredMethod(String name, Class...<?> parameterTypes) | 获得该类某个方法 |
getDeclaredMethods() | 获得该类所有方法 |
- 类中其他重要的方法
方法 | 用途 |
---|---|
isAnnotation() | 如果是注解类型则返回true |
isAnnotationPresent(Class<? extends Annotation> annotationClass) | 如果是指定类型注解类型则返回true |
isAnonymousClass() | 如果是匿名类则返回true |
isArray() | 如果是一个数组类则返回true |
isEnum() | 如果是枚举类则返回true |
isInstance(Object obj) | 如果obj是该类的实例则返回true |
isInterface() | 如果是接口类则返回true |
isLocalClass() | 如果是局部类则返回true |
isMemberClass() | 如果是内部类则返回true |
ClassTest.java
public class ClassTest {
@Test
/**
* 获取Class]
* 1.通过类名.class
* 2.对象.getClass()
* 3.Class.forname
*/
public void demo1() throws ClassNotFoundException{
//1.通过类名.class
Class class1=Person.class;
//2.对象.getClass()
Person person=new Person();
Class class2=person.getClass();
//3.Class.forname
Class class3=Class.forName("com.imooc.reflect.test.Person");
}
}
Constructor类 (代表类的构造方法)
方法 | 用途 |
---|---|
newInstance(Object... initargs) | 根据传递的参数创建类的对象 |
ConstructorTest.java
public class ConstructorTest {
@Test
/**
* 获取无参数构造方法
*/
public void demo1() throws Exception{
Class class1= Class.forName("com.imooc.reflect.test.Person");
Constructor c=class1.getConstructor();
Person person=(Person) c.newInstance();
}
@Test
public void demo2() throws Exception{
Class class1= Class.forName("com.imooc.reflect.test.Person");
Constructor c=class1.getConstructor(String.class,String.class);
Person person=(Person) c.newInstance("张三","男");
System.out.println(person);
}
}
Field类(代表类的成员变量(成员变量也称为类的属性))
1.Field类代表某个类中的一个成员变量,并提供动态的访问权限
2.Field对象的获得
--得到所有成员变量
- Field[ ] fields =c.getFields();//取得所有public属性(包括父类继承)
- Field[ ] fields =c.getDeclaredFields();//取得所有public属性(包括父类继承)
--指定成员变量
- Field name=c.getField("name");
- Field name=c.getDeclaredField("name");
3.设置Field变量是否可以访问
--field.setAccessible(boolean);
4.Field变量值的读取,设置
--field.get(obj)
--field.set(obj,value);
方法 | 用途 |
---|---|
equals(Object obj) | 属性与obj相等则返回true |
get(Object obj) | 获得obj中对应的属性值 |
set(Object obj, Object value) | 设置obj中对应属性值 |
FieldTest.java
public class FieldTest {
@Test
//测试公有属性
public void demo1() throws Exception{
//获得Class
Class class1= Class.forName("com.imooc.reflect.test.Person");
//获得属性
Field field=class1.getField("name");
//操作属性:p.name
Person p=(Person) class1.newInstance();
field.set(p,"历是");//p.name="历是"
Object obj= field.get(p);
System.out.println(obj);
}
@Test
//测试私有属性
public void demo2() throws Exception{
Class class1= Class.forName("com.imooc.reflect.test.Person");
Field field=class1.getDeclaredField("sex");
Person p=(Person) class1.newInstance();
//私有属性,需要设置一个课访问的权限
field.setAccessible(true);
field.set(p,"男");//p.name="历是"
Object obj= field.get(p);
System.out.println(p);
System.out.println(obj);
}
}
Method类(代表类的方法)
1.Method对象的获取
--获取所有方法
getDeclaredMethod();
getMethod();
--获取指定方法
getDeclaredMethod(String name ,Class<?>...patameterTypes);
getMethod(String name ,Class<?>...patameterTypes);
2.通过反射执行方法
invoke(Oblect obj,Object...args)
方法 | 用途 |
---|---|
invoke(Object obj, Object... args) | 传递object对象及参数调用该对象对应的方法 |
MethodTest.java
public class MethodTest {
@Test
//测试公有属性
public void demo1() throws Exception{
//获得Class
Class class1= Class.forName("com.imooc.reflect.test.Person");
//实例化:
Person person=(Person) class1.newInstance();
//获得公有方法
Method method=class1.getMethod("eat");
//执行方法
method.invoke(person);
}
@Test
//测试私有属性
public void demo2() throws Exception{
//获得Class
Class class1= Class.forName("com.imooc.reflect.test.Person");
//获得私有属性
Person person=(Person) class1.newInstance();
//获得方法
Method method=class1.getMethod("run");
//私有属性,需要设置一个课访问的权限
method.setAccessible(true);
//执行方法
method.invoke(person,null);
}
@Test
public void demo3() throws Exception{
//获得Class
Class class1= Class.forName("com.imooc.reflect.test.Person");
//获得私有属性
Person person=(Person) class1.newInstance();
Method method=class1.getDeclaredMethod("sayHello", String.class);
method.setAccessible(true);
Object obj=method.invoke(person,"Tom");
System.out.println(obj);
}
}