反射:获取Class实例、创建运行时类的对象、调用运行时类的指定结构

package JavaFour;

import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @ClassName : ReflectionTest1  //类名
 * @Description : 关于测试的综合测试  //描述
 * @Author : Gao //作者
 * @Date: 2022/3/14  21:50
 */

public class ReflectionTest1 {
    /*
    如何操作运行时类中的指定的属性 -- 需要掌握
     */
    @Test
    public void test() throws Exception {
        //获取Class类的实例
//       ① Class<PersonReflection> personReflectionClass = PersonReflection.class;
//       ② PersonReflection personReflection = new PersonReflection();
//         Class<? extends PersonReflection> aClass1 = personReflection.getClass();
        Class<?> aClass = Class.forName("JavaFour.PersonReflection");

        //创建运行时类的对象
        PersonReflection reflection = (PersonReflection) aClass.newInstance();

        //获取指定的属性
        Field age = aClass.getDeclaredField("age");

        //保证当前属性是可以访问
        age.setAccessible(true);
        //获取、设置当前属性
        age.setInt(reflection, 20);
        System.out.println(age.get(reflection));

    }

    /*
    如何操作运行时类的中指定的方法
     */
    @Test
    public void test1() throws Exception {
        //获取Class类的实例
        Class<?> clazz = Class.forName("JavaFour.PersonReflection");
        //获取运行类的实例
        PersonReflection personReflection = (PersonReflection) clazz.newInstance();
        //获取指定类的方法,参数1 :指明获取的方法的名称  参数2:指明获取的方法的形参列表
        Method show = clazz.getDeclaredMethod("show", String.class);
        //保证当前方法是可以访问的
        show.setAccessible(true);
        //调用invoke()方法执行,参数一:指定方法的调用对象,参数二:给方法的形参赋值
        show.invoke(personReflection, "gaoconghui");

        System.out.println("************如何获取静态方法*******************");
        Method showHobby = clazz.getDeclaredMethod("showHobby");
        showHobby.setAccessible(true);
        //如果调用的运行时类中的方法没有返回值,则此invoke()返回null,注意invoke中的参数为调用静态方法的类
        Object invoke = showHobby.invoke(PersonReflection.class);

    }

    /*
    如何调用运行时类中的指定的构造器
     */
    @Test
    public void test3() throws Exception {
        Class clazz = PersonReflection.class;
        //指定要调用哪个构造器
        Constructor declaredConstructor = clazz.getDeclaredConstructor(String.class);
        declaredConstructor.setAccessible(true);
        //调用此构造器创建运行时类的对象
        Object gaoconghui = declaredConstructor.newInstance("gaoconghui");

        System.out.println(gaoconghui);
    }
}

  • 利用反射和Properties来读取配置文件
@Test
    public void test2() throws Exception {

        Properties pros =  new Properties();
        //此时的文件默认在当前的module下。
        //读取配置文件的方式一:
//        FileInputStream fis = new FileInputStream("jdbc.properties");
//        FileInputStream fis = new FileInputStream("src\\jdbc1.properties");
//        pros.load(fis);

        //读取配置文件的方式二:使用ClassLoader
        //配置文件默认识别为:当前module的src下
        //对于自定义类,使用系统类加载器进行加载
        ClassLoader classLoader = ClassLoaderTest.class.getClassLoader();
        InputStream is = classLoader.getResourceAsStream("jdbc1.properties");
        pros.load(is);

        String user = pros.getProperty("user");
        String password = pros.getProperty("password");
        System.out.println("user = " + user + ",password = " + password);

    }
  • 模拟测试反射的动态性
package com.atguigu.java;

import org.junit.Test;

import java.util.Random;

/**
 * 通过发射创建对应的运行时类的对象
 *
 * @author shkstart
 * @create 2019 下午 2:32
 */
public class NewInstanceTest {

    @Test
    public void test1() throws IllegalAccessException, InstantiationException {

        Class<Person> clazz = Person.class;
        /*
        newInstance():调用此方法,创建对应的运行时类的对象。内部调用了运行时类的空参的构造器。

        要想此方法正常的创建运行时类的对象,要求:
        1.运行时类必须提供空参的构造器
        2.空参的构造器的访问权限得够。通常,设置为public。


        在javabean中要求提供一个public的空参构造器。原因:
        1.便于通过反射,创建运行时类的对象
        2.便于子类继承此运行时类时,默认调用super()时,保证父类有此构造器

         */
        Person obj = clazz.newInstance();
        System.out.println(obj);

    }

    //体会反射的动态性
    @Test
    public void test2(){

        for(int i = 0;i < 100;i++){
            int num = new Random().nextInt(3);//0,1,2
            String classPath = "";
            switch(num){
                case 0:
                    classPath = "java.util.Date";
                    break;
                case 1:
                    classPath = "java.lang.Object";
                    break;
                case 2:
                    classPath = "com.atguigu.java.Person";
                    break;
            }

            try {
                Object obj = getInstance(classPath);
                System.out.println(obj);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }



    }

    /*
    创建一个指定类的对象。
    classPath:指定类的全类名
     */
    public Object getInstance(String classPath) throws Exception {
       Class clazz =  Class.forName(classPath);
       return clazz.newInstance();
    }

}

  • 获取运行时类的带泛型的父类的泛型
 @Test
    public void test4(){
        Class clazz = Person.class;

        Type genericSuperclass = clazz.getGenericSuperclass();
        ParameterizedType paramType = (ParameterizedType) genericSuperclass;
        //获取泛型类型
        Type[] actualTypeArguments = paramType.getActualTypeArguments();
//        System.out.println(actualTypeArguments[0].getTypeName());
        System.out.println(((Class)actualTypeArguments[0]).getName());
    }
  • 获取运行时类声明的注解
   @Test
    public void test7(){
        Class clazz = Person.class;

        Annotation[] annotations = clazz.getAnnotations();
        for(Annotation annos : annotations){
            System.out.println(annos);
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值