欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

了解并学会使用条件反射

最编程 2024-05-05 21:51:36
...

目录

一、反射的应用场景(简单了解)

二、反射的定义

三、关于反射的四个重要的类

四、反射的使用

1.Class获取一个class对象的方式

方式一:forName():

方式二:封装类.Class:

方式三:对象.getClass:

三种方式的使用场景

2.Constructor获取类的构造方法

3.Field获取类的字段(成员变量)

4.Method获取类的成员方法


一、反射的应用场景(简单了解)

在刚学习java时,或者还没有进行实际的项目开发时,反射运用的情况相对较少。

不过也是必须掌握的知识点,而且它也并不难。

学完之后,要运用时,回来复习复习,就差不多了。

反射的主要用途有:

1. 在日常的第三方应用开发过程中,经常会遇到某个类的某个成员变量、方法或是属性是私有的或是只对系统应用开放,这时候就可以利用Java的反射机制通过反射来获取所需的私有成员或是方法 。

2. 反射最重要的用途就是开发各种通用框架,比如在spring中,我们将所有的类Bean交给spring容器管理,无 论是XML配置Bean还是注解配置,当我们从容器中获取Bean来依赖注入时,容器会读取配置,而配置中给的 就是类的信息,spring根据这些信息,需要创建那些Bean,spring就动态的创建这些类。


二、反射的定义

Java的反射(reflection)机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法

他就相当于一个魔镜,在运行状态下,给他照一个类,就能在镜子中看到他所有的内容,包括private修饰的字段、方法等。

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

看定义有点复杂,但是说了这么多,反射实际上就是:

可以获取一个封装类中的任何字段、构造方法、成员方法的一个机制。

如图(*/ω\*):


三、关于反射的四个重要的类

要想使用反射需要铺垫很多东西,才能懂,要使用反射,掌握这些知识是必要的,先不急,慢慢来。

简单看看下面的这四个类,这类四中的有很多关于反射的成员方法,等一下会介绍的奥,留有印象就行。


四、反射的使用

,使用反射获取Student类的属性和方法为例

一下是Student类的定义:

package Test1;

/**
 * Created with IntelliJ IDEA
 * Description:
 * User:34398
 * Date:2024-05-04
 * Time:10:33
 */
public class Student {
    public String Happy;

    private String name;
    private int age;


    private Student(String happy) {//私有的有参数构造方法
        this.Happy = happy;
    }


    public Student() {
    }//无参构造方法


    public Student(String name, int age) {//有参构造方法
        this.name = name;
        this.age = age;
    }


    private String setHappys(String happy){//私有含参数,成员方法
        this.Happy=happy;
        System.out.println("爱好:"+this.Happy);
return happy;

    }

    private void printfName() {//私有成员方法
        System.out.println("名字:" + this.name);
    }

    public void printfAge() {//公有成员方法
        System.out.println("年龄:" + this.age);
    }
    
    
    
    //一下是获取字段的方法
    public String getHappy() {
        return Happy;
    }

    public void setHappy(String happy) {
        Happy = happy;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {//重写一下toString
        return "Student{" +
                "Happy='" + Happy + '\'' +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

1.Class获取一个class对象的方式

获取一个class对象的方式有三种。

方式一:forName():

代码中的clazz1就是我们获取到的class对象了。

值得注意的是:

forName()中的全类名,不需要自己写,因为有时候路径名很长,自己写容易错。

我们可以用idea进行拷贝。

具体做法:

打开idea,右键Student类,选择Copy Path/Reference,点击:

然后进入这个界面,在点击Copy Reference,粘贴到forName()的参数列表中即可:

方式二:封装类.Class:

此时,clazz2也是Student的class对象。

方式三:对象.getClass:

注意,class对象只会存在一个,不会创建多个!

上述代码中的clazz1/clazz2/clazz3实际上指向的都是一个class对象:

三种方式的使用场景

第一种方式用的最多,一般都用forName()

第二种方式,一般当做一个参数进行传递        

第三种方式,在有封装类的对象时,才可以用


2.Constructor获取类的构造方法

Class类中的方法有很多,关于获取构造方法的方法就有4个。

不过好消息是,不用特意去记,因为他们的规律性极强!

助记技巧:

getConstructors()有个s,是复数形式,返回所有的公有构造方法(数组形式)

getDeclaredConstructors()多了个单词,declared,意思是声明,就是告诉编译器,他连private修饰的构造方法也要放进来

getDeclaredConstructor()和getConstructor()不带有s,是单数,所以返回一个构造方法

如果记住了这四个方法,下面获取字段和成员方法的方法基本上也就记住了。


下面是代码实操,获取类的构造方法:

1.获取所有公有构造方法:

执行结果:


2.获取所有构造方法,包括私有的:

执行结果:

此时,Student类中的所有构造方法,都在这里了。


3.获取单个构造方法:

注意:

获取单个构造方法时,

依照传入的参数个数,类型,顺序来判断具体获取到那个构造方法!

执行结果:

小细节:

如果是要获取有参构造方法,参数要与类中的一直,顺序也不能改变,并且要在类型后面点一个class,获取字节码文件。

例如:

String.class

int.class


获取这些构造方法有什么用呢?

用处可多了,可以得到他们的访问修饰权限符、构造方法的参数等等。

idea对方法的提示和填入参数的提示,底层就是用这个实现的。


4.获取访问修饰权限符

注意:

访问权限修饰符的类型使用int型表示的,具体参照表格(了解即可):

执行结果:

1正好就是public


5.获取构造方法的参数类型

执行结果:


6.用获取的构造方法创建封装类的对象

没错,既然我们可以获取封装类的构造方法,那么就可实例化一个封装类的对象.

在Constructor类中调用newInstance(构造方法的参数)方法即可:

助记技巧:
记住newInstance是一个创建对象的方法也很容易,在英文中,new就是创建的意思,
instance就是对象的意思。

执行结果:

竟然报错了!

原因是:

constructor2是一个私有的构造方法

虽然我们可以通过getDecclaredConstructor()获取这个构造方法,

但是却不能直接用

解决办法:

constructor2.setAccssible(true)——临时取消权限校验

即可。

运行结果:

3.Field获取类的字段(成员变量)

执行结果:

其他的比如,所有字段/访问权限修饰符/数据类型等,

格式和获取构造方法的方式可以说一模一样,这里就不多演示了,都是写重复的方式,所以说反射其实并不难。

比如获取name的类型:

执行结果:


另外,Field还有特有的方法,可以获取并且修改成员变量记录的值(在new了一个封装类的对象后)

运行结果:

4.Method获取类的成员方法

其实写完前三个,这个就没有什么好写的了几乎就是十以内的加减法,换着数字考你。

值得注意的是,Method类拥有独属于自己的方法,例如:
获取方法抛出的异常,

获取方法的返回值,

调用获取的方法等等。

执行结果:


以上就是这篇文章的全部内容,自己动手试试,这块内容还是很看实践的。如果可以独立把代码敲出来,说明你就掌握的差不多了。

关于反射这块内容如果还有不清楚的,小编很推荐看一下B站的黑马程序员,讲的很细节,基本都是嚼碎了,喂给你的。

B站链接:java进阶教程进阶教程

推荐阅读