Java重点基础:反射机制

Wesley13
• 阅读 781

一、什么是反射?


Java反射说的是在运行状态中,对于任何一个类,我们都能够知道这个类有哪些方法和属性。对于任何一个对象,我们都能够对它的方法和属性进行调用。我们把这种动态获取对象信息和调用对象方法的功能称之为反射机制。

二、反射的三种方式


这里需要跟大家说一下,所谓反射其实是获取类的字节码文件,也就是.class文件,那么我们就可以通过Class这个对象进行获取。

1、第一种方式

Java重点基础:反射机制

这个方法其实是Object的一个方法,Class继承了Object,所以我们可以直接使用。

public class Test02 {    public static void main(String[] args) {        // 创建一个对象        Test02 t = new Test02();        // 获取该对象的Class对象        Class c = t.getClass();                // 获取类名称        System.out.println(c.getName()); // com.ms.Test02    }}

2、第二种方式

public class Test02 {    public static void main(String[] args) {        Class c = Test02.class;        // 获取类名称        System.out.println(c.getName()); // com.ms.Test02    }}

3、第三种

这里需要注意,通过类的全路径名获取Class对象会抛出一个异常,如果根据类路径找不到这个类那么就会抛出这个异常。

public class Test02 {    public static void main(String[] args) {        try {            // 根据类的全路径名获取            Class c = Class.forName("com.ms.Test02");            // 获取类名称            System.out.println(c.getName()); // com.ms.Test02                    } catch (ClassNotFoundException e) {            e.printStackTrace();        }    }}

那么这3中方式我们一般选用哪种方式呢?第一种已经创建了对象,那么这个时候就不需要去进行反射了,显得有点多此一举。第二种需要导入类的包,依赖性太强。所以我们一般选中第三种方式。

三、通过反射获取类的构造方法、方法以及属性


1、获取构造方法

public class Test01 {    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException {        // 加载Class对象        Class c = Class.forName("com.reflect.User");        System.out.println("===========================获取所有公用的构造方法==============================");        // 获取所有公用的构造方法        Constructor[] constructors = c.getConstructors();        for (Constructor constructor : constructors) {            System.out.println(constructor);        }        System.out.println("=============================获取所有的构造方法============================");        // 获取所有的构造方法        Constructor[] declaredConstructors = c.getDeclaredConstructors();        for (Constructor declaredConstructor : declaredConstructors) {            System.out.println(declaredConstructor);        }        System.out.println("=============================获取公有 & 无参的构造方法============================");        Constructor constructor = c.getConstructor(null);        System.out.println(constructor);        System.out.println("=============================获取公有 & 有参的构造方法============================");        Constructor constructor1 = c.getConstructor(new Class[]{String.class, Integer.class, String.class});        System.out.println(constructor1);        System.out.println("=============================获取私有 & 有参 构造方法============================");        Constructor declaredConstructor1 = c.getDeclaredConstructor(new Class[]{String.class});        System.out.println(declaredConstructor1);    }}

结果:

Java重点基础:反射机制

     

2、获取类属性

public class Test02 {    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {        // 获取Class对象        Class<?> clazz = Class.forName("com.reflect.User");        System.out.println("=====获取所有的公共字段=====");        Field[] fields = clazz.getFields();        for (Field field : fields) {            System.out.println(field);        }        System.out.println("=====获取所有的字段(公开的、私有的)=====");        Field[] declaredFields = clazz.getDeclaredFields();        for (Field declaredField : declaredFields) {            System.out.println(declaredField);        }        System.out.println("=====获取公有字段并使用=====");        // 获取指定公有字段        Field field = clazz.getField("name");        // 获取一个公有构造方法,然后实例化        Object obj = clazz.getConstructor().newInstance();        // 为属性设置值        field.set(obj, "张三");        // 测试,看设置的值是否成功        User user = (User) obj;        System.out.println(user.getName());        System.out.println("=====获取私有字段并使用=====");        Field field1 = clazz.getDeclaredField("sex");        // 获取构造函数,实例化对象        Object obj1 = clazz.getConstructor().newInstance();        // 暴力反射        field1.setAccessible(true);        // 给属性设置值        field1.set(obj1, "男");        // 测试        User u = (User) obj1;        System.out.println(u.getSex());    }}

结果

Java重点基础:反射机制

     

这里需要注意,在获取私有属性的时候如果没有进行暴力反射,那么会抛出下面这个异常。

Java重点基础:反射机制

     

3、获取类中的方法

先定义几个方法

public void method1(String str) {    System.out.println("public 修饰的方法");}private void method2() {    System.out.println("private 修饰的方法");}String method3(String name, Integer age, String sex) {    System.out.println("默认修饰 " + name + " " + sex + " " + age + "岁");    return name + sex + age;}protected void method4() {    System.out.println("protected 修饰的方法");}

正题

public class Test03 {    public static void main(String[] args) throws Exception {        // 获取Class对象        Class<?> clazz = Class.forName("com.reflect.User");        System.err.println("======获取所有的public修饰的方法=====");        Method[] methods = clazz.getMethods();        for (Method method : methods) {            System.out.println(method);        }        Thread.sleep(1000);        System.err.println("======获取所有的方法=====");        Method[] declaredMethods = clazz.getDeclaredMethods();        for (Method declaredMethod : declaredMethods) {            System.out.println(declaredMethod);        }        Thread.sleep(1000);        System.err.println("======获取特定方法(带参)并使用=====");        Method method1 = clazz.getMethod("method1", String.class);        System.out.println(method1);        Thread.sleep(1000);        System.err.println("======获取特定方法(不带参)并使用=====");        Method method2 = clazz.getDeclaredMethod("method2");        System.out.println(method2);        System.err.println("======获取特定方法(多个参数)并使用=====");        Method method3 = clazz.getDeclaredMethod("method3", String.class, Integer.class, String.class);        // 获取构造方法,实例化一个对象        Object obj = clazz.getConstructor().newInstance();        // 给方法传值        Object invoke = method3.invoke(obj, "小涛", 24, "男");        // 测试        System.out.println(invoke);    }}

结果

Java重点基础:反射机制

Java重点基础:反射机制

    

这里需要注意的就是当一个方法需要传入多个参数值的时候,一定要注意。踩了一点坑。

四、反射执行main方法


public class Main {    public static void main(String[] args) {        System.out.println("main方法执行了");    }}

反射调用

public class Test04Main {    public static void main(String[] args) {        try {            // 获取Class对象            Class<?> clazz = Class.forName("com.reflect.Main");            // 获取Main方法            Method method = clazz.getMethod("main", java.lang.String[].class);            // 调用            method.invoke(null, (Object) new String[]{"a"});        } catch (Exception e) {            e.printStackTrace();        }    }}

这里需要告诉大家,在导String包的时候千万要看清楚,我在这填了20多分钟的坑。

Java重点基础:反射机制

     

五、总结

看到这里你已经对反射有了一个简单的了解,可以使用反射获取一些属性方法,其实我们平时写代码很少用到反射技术,但是在我们使用的一些主流框架中反射技术应用是非常广泛的,所以学好反射也是非常有必要的。

今天就写到这里,下篇给大家分享一下利用反射做一些有应用型的例子。

-----------------------华丽的分割线-------------------------

另外告诉大家一个好消息,双12已经到来了,那么不消费一波作为程序员好像有点说不过去,正好极客时间最近的课程在做活动,大大赶紧围观吧。活动期限12.12-12.16,大家看到自己的喜欢的拿起手机不要犹豫,扫描课程二维码即可购买,赶紧速速选购吧!

Java重点基础:反射机制

Java重点基础:反射机制

Java重点基础:反射机制

Java重点基础:反射机制

Java重点基础:反射机制

Java重点基础:反射机制

Java重点基础:反射机制

Java重点基础:反射机制

Java重点基础:反射机制

更多内容请关注“一个程序员的成长

Java重点基础:反射机制

[推荐阅读]

设计模式之 - 装饰者模式

设计模式之 - 简单工厂模式

设计模式之 - 策略落实

本文分享自微信公众号 - 一个程序员的成长(xiaozaibuluo)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Wesley13 Wesley13
3年前
java中 什么是反射?
JAVA反射机制是在运行状态中,对于任意一个实体类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。JAVA反射(放射)机制:“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言(https://www.oschina.net/act
浪人 浪人
3年前
Java基础与提高干货系列——Java反射机制
前言今天介绍下Java的反射机制,以前我们获取一个类的实例都是使用new一个实例出来。那样太low了,今天跟我一起来学习学习一种更加高大上的方式来实现。正文Java反射机制定义Java反射机制是指在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以
Wesley13 Wesley13
3年前
java中的反射和代理
  Java反射机制可以动态地获取类的结构,动态地调用对象的方法,是java语言一个动态化的机制。java动态代理可以在不改变被调用对象源码的前提下,在被调用方法前后增加自己的操作,极大地降低了模块之间的耦合性。这些都是java的基础知识,要想成为一名合格的程序猿,必须掌握!Java反射机制 JAVA反射机制是在运行状态中,对于任意一个类,都能够知
Wesley13 Wesley13
3年前
java面试(反射)05
1.什么是反射JAVA反射机制是在运行状态中,对于任意一个类,都能够获取这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取类信息以及动态调用对象内容就称为java语言的反射机制。2.反射的作用在运行时判断任意一个对象所属的
lzy lzy
3年前
RPC框架手撕之路---java反射以及动态代理机制
在上一篇文章中,我们提到了,RPC框架所需要的java基础,第一点就是java的动态代理机制,动态代理机制的基础是反射,无论是在实际编程或者是面试时,都是java知识的重中之重。java反射:定义:在运行状态中,对于任意一个类,都能够知道这一个类的所有属性和方法,对于任意一个对象都能够通过反射机制调用一个类的任意方法,这种动态获取类信息以及动态调用类方法
御弟哥哥 御弟哥哥
3年前
Java基础与提高干货系列 -- Java反射机制
前言今天介绍下Java的反射机制,以前我们获取一个类的实例都是使用new一个实例出来。那样太low了,今天跟我一起来学习学习一种更加高大上的方式来实现。正文Java反射机制定义Java反射机制是指在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性
桃浪十七丶 桃浪十七丶
3年前
工厂模式实例(顺便回忆反射机制的应用)
一、原理反射机制的原理JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。工厂模式自述所谓工厂模式,是说由某个产品类接口、产品实现类、工厂类、客户端(单元测试主类)构成的一个模式,大程度的降低了代码的
Wesley13 Wesley13
3年前
Java基础之反射(非常重要)
反射是框架设计的灵魂(使用的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码))一、反射的概述JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法
Wesley13 Wesley13
3年前
Java反射机制及适用场景
什么是Java反射机制?JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的以及动态调用对象的方法的功能称为Java的反射机制。反射的适用场景是什么?1.当你做一个软件可以安装插件的功能,你连插件的类型名称都不知道,你怎么实例化这个对象呢