通过一个例子来讲述反射

一、什么叫反射:

1、定义:

反射机制是在运行时,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意个对象,能够调用它的任意一个方法。在java中,只要给定类的名字,就可以通过反射机制来获得类的所有信息

这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制

2、反射的实现方式:

第一步:获取Class对象,有四种方法:

1)Class.forName("类的路径")

2)类名.class

3)对象名.getClass

4)基本类型的包装类,可以调用包装类的Type属性来获得该包装类的Class对象

3、实现java反射的类:

1)Class:表示正在运行的Java应用程序中的类和接口 注意:所以获取对象的信息都需要Class类来实现

2)Field:提供有关类和接口的属性信息,以及对它的动态访问权限。

3)Constructor:提供关于类的单个构造方法的信息以及它的访问权限。

4)Method:提供类或接口中某个方法的信息

4、反射机制的优缺点:

优点:1)能够运行时动态获取类的实例,提高灵活性;2)与动态编译结合

缺点:1)使用反射的性能较低,需要解析字节码,将内存中的对象进行解析。

             解决方案:1、通过setAccessible(true)关闭JDK的安全检查来提高反射速度

                               2、多次创建一个类的实例时,有缓存会快很多

                               3、ReflectASM工具类,通过字节码生成的方式加快反射速度

         2)相对不安全,破坏了封装性(因为通过反射可以获得私有方法和属性)

二、总体来说:

1、根据配置文件re.properties指定信息,创建对象并调用方法

classfullpath=com.hspedu.Cat
method=hi

2、这样的需求在学习框架时特别多,即通过外部文件配置,在不修改源码的情况下,来控制程序,也符合设计模式的ocp原则(开闭原则)

3、快速入门 com.hspedu.reflection.question

        ReflectionQuestion.java

三、实践:

      1、首先在idea中创建一个项目,然后在src下面创建一个re.properties文件,内容如下:

 

     2、然后创建com.hspedu包,在包下面创建Cat.java,内容如下:

public class Cat {
    private String name="招财猫";
    public void hi(){ //常用方法
        System.out.println("hi "+name);
    }

    public void cry(){
        System.out.println("cry "+name);
    }
}

      3、创建com.hspedu.reflection.question包,在包下面创建ReflectionQuestion.java,内容如下:

/**
 * @User: 老潘
 * @date 2022年09月16日15:43
 * 反射问题的引入
 */
public class ReflectionQuestion {
    public static void main(String[] args) throws Exception{
        //根据配置文件 re.properties 指定信息,创建Cat对象并调用方法hi

        //传统的方式 new 对象->>调用方法
//        Cat cat=new Cat();
//        cat.hi();
        // cat.cry  就是说传统方法 用对象实例调用其他方法需要修改代码

        //我们尝试做一做 ->明白反射

        //1、使用Properties类,可以读写配置文件
        Properties properties=new Properties();
        properties.load(new FileInputStream("src\\re.properties"));
        String classfullpath = properties.get("classfullpath").toString();
        String method = properties.get("method").toString();
        System.out.println("classfullpath="+classfullpath);
        System.out.println("method="+method);

        //2、创建对象 ,传统的方法,行不通=》反射机制
//        new com.hspedu.Cat();



        //3、使用反射机制解决
        //(1) 加载类,返回Class类型的对象cls
        Class<?> cls = Class.forName(classfullpath);
        // System.out.println("cls:"+cls);
        //(2) 通过cls得到你加载的类 com.hspedu.Cat的对象实例
        Object o = cls.newInstance();
        System.out.println("o的运行类型="+o.getClass());  //运行类型
        //(3) 通过cls得到你加载的类  com.hspedu.Cat 的 methodName "hi" 的方法对象
        // 即:在反射中,可以把方法视为对象(万物皆对象)
        Method method1 = cls.getMethod(method); // 调用方法只需要修改配置文件中method的值
        //(4) 通过method1 调用方法:即通过方法对象来实现调用方法
        System.out.println("========================");
        method1.invoke(o);  //传统方法  对象.方法() ,反射机制  方法.invoke(对象)
    }
}

最后一张总结图:

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一个常见的例子是在 Android 中使用反射来动态获取类的信息。比如,我们可以通过反射来获取一个类的所有属性和方法,并根据需要进行调用、修改等操作。 以下是一个简单的示例,演示如何使用反射来获取类的信息: ```java public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getInfo(Student.class); } private void getInfo(Class<?> clazz) { Field[] fields = clazz.getDeclaredFields(); Method[] methods = clazz.getDeclaredMethods(); for (Field field : fields) { Log.d("MainActivity", "Field name: " + field.getName()); } for (Method method : methods) { Log.d("MainActivity", "Method name: " + method.getName()); } } } class Student { private String name; private int age; public Student(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } } ``` 在上面的示例中,我们定义了一个 Student 类,并使用反射机制来获取该类的所有属性和方法。具体来说,我们通过 `clazz.getDeclaredFields()` 方法获取 Student 类的所有属性,通过 `clazz.getDeclaredMethods()` 方法获取 Student 类的所有方法。然后,我们遍历这些属性和方法,并使用 `Log.d()` 方法输出它们的名称。 当我们运行该示例时,可以看到如下的日志输出: ``` Field name: name Field name: age Method name: getName Method name: getAge Method name: setName Method name: setAge ``` 从输出结果中可以看出,我们使用反射成功地获取了 Student 类的所有属性和方法,并且可以根据需要进行调用、修改等操作。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值