我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Java中的反射机制基本运用详解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Java中的反射机制基本运用详解

Java中的反射机制基本运用

看完反射可以了解一下注解

注解annotation://www.jb51.net/article/221276.htm

1、什么是反射(reflect)

反射是java的动态机制,它允许将对象的实例化,方案的调用,属性的操作等从编码期确定转移到程序运行期确定。

反射能大大提高代码的灵活度。但同时也带来了更多的系统开销和较慢的运行效率,因此程序不能过度依赖反射。

2、反射机制提供的功能

  • 在运行时判断任意一个对象所属的类
  • 在运行时构造任意一个类的对象(实例化)
  • 在运行时判断任意一个类所具有的成员变量和方法
  • 在运行时调用任意一个对象的方法——动态代理

3、反射->获取类对象

在开始之前创建一个实体类,用于测试反射机制


package reflect_text;

public class Person {
    private String name = "刘瑜澄";//设置初始值
    private int age = 22;
    public Person() {//无参构造
    }
    public Person(String name, int age) {//有参构造
        this.name = name;
        this.age = age;
    }
    public void sayHello() {//无参方法
        System.out.println(name + ":使用sayHello方法");
    }
    public void sayGoodBye() {//无参方法
        System.out.println(name + ":使用sayGoodBye方法");
    }
    public void say(String info) {//有参方法
        System.out.println(name + ":" + info);
    }
    public void say(String info, int sum) {//有参方法(重载say方法)
        for (int i = 0; i < sum; i++) {
            System.out.println(name + ":" + info);
        }
    }
    private void privateMethod() {//私有方法
        System.out.println(name + ":这是一个私有方法");
    }
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

以上这个用于测试反射的实体类创建成功后,先学习反射中是如何获取类对象的。

反射的第一步就是要获取操作类的类对象,即一个Class的实例,JVM中每个被加载的类有且只有一个类对象与之对应,获取到这个类对象后我们就可以通过这个类对象来了解该类的一切信息(类名、有哪些方法、属性等等) 以便在程序运行期间通过反射机制进行相关操作

这里介绍三种获取类对象的方式:

  • (包名.)类名.class

Class personClass = reflect_text.Person.class;
Class intClass = int.class;

这种方式最直接,但是由于是靠硬编码形式写死(编译期间已经确定),因此不够灵活。但是需要注意,基本类型(int\double等)只能通过这种方式获取类对象

  • Class.forName(String className)

Class personClass = Class.forName("reflect_text.Person");
Class stringClass = Class.forName("java.lang.String");

这种方式较为常用,遵循运行期绑定。

  • 类加载器ClassLoader

Class stringClass = ClassLoader.getSystemClassLoader().loadClass("java.lang.String");
Class personClass = ClassLoader.getSystemClassLoader().loadClass("reflect_text.Person");

在这一节中介绍几个简单的方法:


getName()
获取类的完全限定名:包名.类名
getSimpleName()
仅仅获取类名
getMethods()
返回一个Method数组,获取class所表示的类的所有公开方法(包含从超类中继承的方法)

例子:


		Scanner scanner = new Scanner(System.in);
		Class cls = Class.forName(scanner.nextLine());//运行期绑定
        String name = cls.getName();//获取类的完全限定名:包名.类名
        System.out.println("完全限定名 = " + name);
        name = cls.getSimpleName();//仅获取类名
        System.out.println("仅类名 = " + name);
        Method[] methods = cls.getMethods();
        for (Method m : methods) {
            System.out.print(m.getName()+"\t");
        }

4、反射->利用无参构造实例化对象

Class类中提供了一个方法newInstance()来实例化,该方法要求此类必须具有无参构造器,它是通过无参构造器实例化对象的。


		Person person = new Person();
        //1获取要实例化的类的类对象
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入类名:");
        Class cls = Class.forName(scanner.nextLine());
        
        Object obj = cls.newInstance();
        System.out.println("obj = " + obj);

在这里插入图片描述

5、反射->利用有参构造实例化对象


getConstructor()
//获取无参构造器,可以利用无参构造器实例化对象,但这个方法对于使用无参构造器实例化对象可有可无
getConstructor(类对象)
//通过类对象获取特定的构造器,该参数列表是根据特定构造器的参数列表类型来决定的,如
		getConstructor(String.class, int.class)
		即为调用Person类中两个参数的有参构造器
		public Person(String name, int age) {//有参构造
    		this.name = name;
    		this.age = age;
		}

举例


		//加载类对象
        Class cls = Class.forName("reflect.Person");
        //通过类对象获取特定的构造器
        Constructor c = cls.getConstructor(String.class, int.class);
        Object o = c.newInstance("流年", 21);//实例化
        System.out.println(o);

结果可知初始值已经被修改

在这里插入图片描述

6、反射->调用无参方法


getMethod(String MethodName)
获取类对象的MethodName方法,返回值类型为Method
invoke(Object object)
执行object对象的某方法

举例


		//一般调用方法的做法-------------------
        Person p = new Person();//实例化对象
        p.sayHello();//调用该对象方法
        //反射机制调用方法-----------------------
        //1、实例化对象
        Class cls = Class.forName("reflect_text.Person");
        Object o = cls.newInstance();
        //2、调用o的sayHello方案
        //2.1通过Class获取Person的sayHello方法
        Method method = cls.getMethod("sayHello");
        //2.2调用o的该方法
        method.invoke(o);//等效于一般方法中的o.sayHello()

可见两种操作均能达到一样的效果

在这里插入图片描述

7、反射->调用有参方法


getMethod(String MethodName, 类对象)
获取类对象的MethodName有参方法,并传入对应参数类型的类对象,返回值类型为Method

举例


		//一般调用有参方法------------------------
        Person p = new Person();
        p.say("七夕快乐~");
        p.say("七夕快乐~",3);
        //反射机制调用有参方法---------------------
        Class cls = Class.forName("reflect_text.Person");
        Object o = cls.newInstance();
        //调用say(String info)方法
        Method m1 = cls.getMethod("say", String.class);
        m1.invoke(o, "春节快乐~");
        //调用say(String info, int sum)
        Method m2 = cls.getMethod("say", String.class, int.class);
        m2.invoke(o,"春节快乐~",3);

通过结果可以看到,效果都是一样的

在这里插入图片描述

8、反射->访问私有方法

注意:反射访问私有的方法,但是会破坏类的封装性


getDeclaredMethod(String MethodName)
可以仅获取此类定义的所有方法,包含私有方法
setAccessible(boolean flag)
开启私有方法的访问权限

举例


		//正常情况下,在本类中不可以访问外部的私有方法
		//但在反射机制中可行
		Class cls = Class.forName("reflect_text.Person");
        Object o = cls.newInstance();
        Method method = cls.getDeclaredMethod("privateMethod");
        method.setAccessible(true);//打开访问权限
        method.invoke(o);

在这里插入图片描述

9、反射->类加载路径

加载资源时常用相对路径,之前学习的相对路径./由于运行环境不同,位置并非固定,因此实际开发中使用较少。
接下来介绍,在开发中常用的类加载路径

常用的路径通常为类的加载路径,有两个:

1:类对象.getResource()与当前类所处同一目录

2:类加载器.getResource()类加载路径,类的package定义中根包位置。


例如:有一个类:
package reflect_text;
public class WebServer{
     ……
}
在WebServer类中,当我们使用上述两种方式获取路径时他们的对应位置为:
WebServer.class.getResource()
当前WebServer所在的目录(编译后的class文件所在目录)
WebServer.class.getClassLoader().getResource()
则是在WebServer的包的最上级,即com包的上一级

package reflect_text;
public class ReflectDemo {
		File dir = new File(ReflectDemo.class.getResource(".").toURI());
        System.out.println("dir = " + dir);
        //dir = D:\ClassCode\JavaSE_API\out\production\JavaSE_API\reflect
        File dir2 = new File(ReflectDemo.class.getClassLoader().getResource(".").toURI());
        System.out.println("dir2 = " + dir2);
        //dir2 = D:\ClassCode\JavaSE_API\out\production\JavaSE_API
}

在这里插入图片描述

总结

本片文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注编程网的更多内容!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Java中的反射机制基本运用详解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

java反射机制最详解

目录java反射机制什么是反射?反射的功能:反射常用类:1.Class枚举类2.Constructor构造器3.Method方法类4.Field变量类反射运行指示图通过反射获取对象总结java反射机制什么是反射?在java开发中有一个非常重要的概念就是java
2020-08-07

Java-反射机制(超详解)

Java反射机制概述 前言一、Java反射机制概述1. Java Reflection2. 动态语言 vs 静态语言 二、 Class类的理解1. 类的加载过程1.1 初步了解1.2 类的加载过程图解1.3 了解:什么时候会发
2023-08-17

Java 反射机制的实例详解

Java 反射机制的实例详解前言 今天介绍下Java的反射机制,以前我们获取一个类的实例都是使用new一个实例出来。那样太low了,今天跟我一起来学习学习一种更加高大上的方式来实现。正文 Java反射机制定义Java反射机制是指在运行状态中
2023-05-31

Java 反射机制详解及实例

Java 反射机制详解及实例反射,当时经常听他们说,自己也看过一些资料,也可能在设计模式中使用过,但是感觉对它没有一个较深入的了解,这次重新学习了一下,感觉还行吧! 一,先看一下反射的概念: 主
2023-05-31

如何在 Java 中使用反射机制?(java中的反射机制怎么使用)

在Java编程中,反射机制是一个强大的工具,它允许程序在运行时检查和操作类、对象、方法和字段。通过反射,我们可以在运行时动态地获取类的信息,创建对象,调用方法,以及访问和修改字段。这使得我们的程序更加灵活和可扩展。一、反射的基本概念
如何在 Java 中使用反射机制?(java中的反射机制怎么使用)
Java2024-12-20

详解java中反射机制(含数组参数)

详解java中反射机制(含数组参数)java的反射是我一直非常喜欢的地方,因为有了这个,可以让程序的灵活性大大的增加,同时通用性也提高了很多。反射原理什么的,我就不想做过大介绍了,网上一搜,就一大把。(下面我是只附录介绍下)Reflecti
2023-05-31

Python基础学习之反射机制详解

在Python中,反射是指通过一组内置的函数和语句,在运行时动态地访问、检查和修改对象的属性、方法和类信息的机制。本文将通过简单的示例和大家讲讲Python中的反射机制,希望对大家有所帮助
2023-03-22

Java安全基础之Java的反射机制

利用Java的反射机制,我们可以无视类方法、变量访问权限修饰符,调用任何类的任意方法、访问并修改成员变量值,但是这样做可能导致安全问题,如果一个攻击者能够通过应用程序创建意外的控制流路径,就有可能绕过安全检查发起相关攻击。

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录