反射机制概述
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);
    }
}
反射作用(个人理解):可以通过反射来动态的调用声明类中的私有属性、私有方法。
 
                    
                     
                    
                 
                    
                 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号