反射机制概述
作者:互联网
反射机制概述
Java.lang.Class类的理解
-
类的加载过程:程序在经过javac.exe命令后,会生成一个或多个字节码文件(.class结尾),接着我们使用java.exe命令对某个字节码文件进行解释运行。相当于将某个字节码文件加载到内存中,此过程称为类的加载。加载到内存中的类,我们称为运行时类,就作为Class的一个实例。
-
换句话说,Class的实例对应着一个运行时类。(Class clazz=Person.class)
-
获取Class的实例的方式
package com.yicurtain.Reflect; import org.junit.Test; import java.util.concurrent.Callable; public class reflectTest { // 获取Class的实例的方式 @Test public void test1() throws ClassNotFoundException { // 方式一:调用运行时类的属性:.class Class<Person> clazz1 = Person.class; System.out.println(clazz1); // 方式二:通过运行时类的对象,调用getClass() Person p1 = new Person(); Class clazz2 = p1.getClass(); System.out.println(clazz2); // 方式三:调用Class的静态方法:forName(String classPath) Class clazz3 = Class.forName("com.yicurtain.Reflect.Person"); System.out.println(clazz3); } };
通过反射创建对应的运行时类的对象(*)
package com.yicurtain.Reflect;
import org.junit.Test;
public class newInstanceTest {
@Test
public void test1() throws InstantiationException, IllegalAccessException {
Class<Person> clazz = Person.class;
/*newInstance():调用此方法创建对应的运行时类的对象。内部调用了运行时类的空参构造器。
要想此方法正常的创建运行时类的对象,要求:
1.运行时类必须时提供空参的构造器
2.空参的构造器的访问权限位public或defalut
在javabean中要求提供一个public的空参构造器。原因:
1.便于通过反射,创建运行时类的对象
2.便于子类继承此运行时类时,默认调用super()时,保证父类有此构造器。
*/
Person obj = clazz.newInstance();
System.out.println(obj);
}
}
获取运行时类的完整结构
-
获取属性结构
- getFields():获取当前运行时类及其父类中声明为public访问权限的属性
- getDeclaredFields():获取当前运行时类的所有属性(不考虑权限,不包含父类中声明的属性)
- public int getModifiers() 以整数形式返回此Field的修饰符
- public Class<?> getType() 得到Field的属性类型
- public String getName() 返回Field的名称。
-
获取方法结构
- getMethods():获取当前运行时类及其父类中声明为public访问权限的方法
- getDeclaredMethods():获取当前运行时类中声明的所有方法(不包含父类中声明的方法)
- getAnnotations():获取当前运行时类的方法的注解
- public Class<?> getReturnType()取得全部的返回值
- public Class<?>[] getParameterTypes()取得全部的参数
- public int getModifiers()取得修饰符
- public Class<?>[] getExceptionTypes()取得异常信息
-
获取构造器结构
- getConstructors():获取当前运行时类中声明为public访问权限的构造器
- getDeclaredConstructors():获取当前运行时类中声明的所有构造器
-
获取运行时类的父类
-
getSuperclass():获取运行时类的父类
-
getGenericSuperclass():获取运行时类带泛型的父类
-
获取运行时类带泛型的父类的泛型(功能性代码)
-
-
获取运行时类的接口
- getInterfaces():获取运行时类的接口
-
获取运行时类所在的包
- getPackage:获取运行时类所在的包
调用运行时类的指定属性(*)
- getField():获取运行时类中声明为public的属性(通常不采用)
- getDeclaredField()
package com.yicurtain.Reflect;
import org.junit.Test;
import java.lang.reflect.Field;
public class fieldTest {
@Test
public void test1() throws Exception{
Class<Person> clazz = Person.class;
//创建运行时类的对象
Person person = clazz.newInstance();
// 1. clazz.getDeclaredField(),获取运行时类中指定变量名的属性
Field name = clazz.getDeclaredField("name");
// 2.保证当前属性可访问
name.setAccessible(true);
// 3.设置指定对象的属性值
name.set(person,"Tom");
System.out.println(name.get(person));
}
}
调用运行时类的指定方法(*)
package com.yicurtain.Reflect;
import org.junit.Test;
import java.lang.reflect.Method;
public class methodTest {
@Test
public void test1() throws Exception{
Class<Person> clazz = Person.class;
Person person = clazz.newInstance();
// 1. getDeclaredMethod():参数1:指明获取方法的名称。参数2:指明获取方法的形参列表
Method shownation = clazz.getDeclaredMethod("shownation", String.class);
//2.保证当前方法可访问
shownation.setAccessible(true);
// 3.调用 invoke():参数1:方法的调用者。参数2:给方法形参赋值的实参
Object returnvalue = shownation.invoke(person, "CHN");
//输出返回值
System.out.println(returnvalue);
System.out.println("*******调用静态方法********");
Method show = clazz.getDeclaredMethod("show");
show.setAccessible(true);
show.invoke(Person.class);
}
}
调用运行时类的指定构造器
package com.yicurtain.Reflect;
import org.junit.Test;
import java.lang.reflect.Constructor;
public class constructorTest {
@Test
public void test1() throws Exception{
Class<Person> clazz = Person.class;
//1.调用getDeclaredConstructor():参数1:指明构造器的参数列表
Constructor<Person> constructor = clazz.getDeclaredConstructor(String.class);
//2.保证当前方法可访问
constructor.setAccessible(true);
//3.调用此构造器创建运行时类的对象
Person person = constructor.newInstance("Tom");
System.out.println(person);
}
}
反射作用(个人理解):可以通过反射来动态的调用声明类中的私有属性、私有方法。
标签:反射,class,Class,获取,概述,机制,时类,public,运行 来源: https://www.cnblogs.com/yicurtain/p/15027188.html