首页 > 编程语言 >Java 深入学习(27) —— 反射:运行时的类型信息

Java 深入学习(27) —— 反射:运行时的类型信息

时间:2023-06-08 10:05:06浏览次数:60  
标签:反射 27 Java 类型信息 System Class println class


1 什么是反射


反射(Reflection) 是Java 程序开发语言的特征之一,它允许运行中的 Java 程序获取类的信息,并且可以操作类或对象的内部属性

通过反射,我们可以在运行时获得程序或程序集中每一个类型的成员和成员的信息。

反射的核心是JVM在运行时才动态加载类或调用方法/访问属性,它不需要事先(写代码的时候或编译期)知道运行对象是谁。


2 反射的功能


1.在运行时判断任意一个对象所属的类;
2.在运行时构造任意一个类的对象;
3.在运行时判断任意一个类所具有的成员变量和方法(通过反射甚至可以调用private方法);
4.在运行时调用任意一个对象的方法

重点:是运行时而不是编译时


3 反射的工作原理


当我们编写完一个Java项目之后,每个java文件都会被编译成一个.class文件。

这些Class对象承载了这个类的所有信息,包括父类、接口、构造函数、方法、属性等。

这些class文件在程序运行时会被ClassLoader加载到虚拟机中。

当一个类被加载以后,Java虚拟机就会在内存中自动产生一个Class对象。

我们通过new的形式创建对象实际上就是通过这些Class来创建,只是这个过程对于我们是不透明的而已。

反射的工作原理就是借助Class 、Constructor 、Method 、Field 这四个类在程序运行时动态访问和修改任何类的行为和状态。


4 反射的简单应用


package com.test.class_obj;

import java.lang.reflect.*;
import java.util.regex.*;

public class ShowMethods {
    private static String usage =
            "usage:\n" +
                    "ShowMethods qualified.class.name\n" +
                    "To show all methods in class or:\n" +
                    "ShowMethods qualified.class.name word\n" +
                    "To search for methods involving 'word'";
    private static Pattern p = Pattern.compile("\\w+\\.");
    public static void main(String[] args) {
        if(args.length < 1) {
            System.out.println(usage);
            System.exit(0);
        }
        int lines = 0;
        try {
            // 通过类的完全限定名,查找并加载 Class 对象
            Class<?> c = Class.forName(args[0]);
            Method[] methods = c.getMethods();
            Constructor[] ctors = c.getConstructors();
            if(args.length == 1) {
                for(Method method : methods)
                    System.out.println(
                            p.matcher(method.toString()).replaceAll(""));
                System.out.println("-----------------------------");
                for(Constructor ctor : ctors)
                    System.out.println(p.matcher(ctor.toString()).replaceAll(""));
                lines = methods.length + ctors.length;
            } else {
                for(Method method : methods)
                    if(method.toString().indexOf(args[1]) != -1) {
                        System.out.println(
                                p.matcher(method.toString()).replaceAll(""));
                        lines++;
                    }
                for(Constructor ctor : ctors)
                    if(ctor.toString().indexOf(args[1]) != -1) {
                        System.out.println(p.matcher(
                                ctor.toString()).replaceAll(""));
                        lines++;
                    }
            }
        } catch(ClassNotFoundException e) {
            System.out.println("No such class: " + e);
        }
    }
}

Java 深入学习(27) —— 反射:运行时的类型信息_java


5 反射性能较差的原因

Because reflection involves types that are dynamically resolved, certain Java virtual machine optimizations can not be performed. Consequently, reflective operations have slower performance than their non-reflective counterparts, and should be avoided in sections of code which are called frequently in performance-sensitive applications.

由于反射涉及类型的动态解析,所以无法执行某些Java虚拟机优化。 因此,反射操作比非反射操作具有更慢的性能,应该避免在性能敏感的应用程序中频繁调用的代码段。


6 参考资料

1、深入解析Java反射(1) - 基础
http://www.sczyh30.com/posts/Java/java-reflection-1/#%E4%B8%80%E3%80%81%E5%9B%9E%E9%A1%BE%EF%BC%9A%E4%BB%80%E4%B9%88%E6%98%AF%E5%8F%8D%E5%B0%84%EF%BC%9F

2、学习java应该如何理解反射?
https://www.zhihu.com/question/24304289

3、深入浅出反射
https://zhuanlan.zhihu.com/p/21423208

4、Java Reflection Performance
https://stackoverflow.com/questions/435553/java-reflection-performance


7 反射中的骚操作


通过反射可以无视 诸如 private 之类的访问修饰符

今天在看 http://stamen.iteye.com/blog/1497981 的时候,看到里边说 甚至连 void 都有 对应的 class 对象。

于是突发奇想的尝试了一下

这是 Void.java 的源码

package java.lang;

/**
 * The {@code Void} class is an uninstantiable placeholder class to hold a
 * reference to the {@code Class} object representing the Java keyword
 * void.
 *
 * @author  unascribed
 * @since   JDK1.1
 */
public final
class Void {

    /**
     * The {@code Class} object representing the pseudo-type corresponding to
     * the keyword {@code void}.
     */
    @SuppressWarnings("unchecked")
    public static final Class<Void> TYPE = (Class<Void>) Class.getPrimitiveClass("void");

    /*
     * The Void class cannot be instantiated.
     */
    private Void() {}
}

可以看到 Void 的构造器是私有的。

但是,通过如下的方式就可以使用 Void 私有的构造器啦~~~~

Constructor constructor = Void.class.getConstructor();
        constructor.setAccessible(true);
        Void void_b = (Void) constructor.newInstance();
        System.out.println("------------");
        System.out.println(void_b);
        System.out.println("------------");

Java 深入学习(27) —— 反射:运行时的类型信息_java_02

学习Spring必学的Java基础知识(1)—-反射
http://stamen.iteye.com/blog/1497981



标签:反射,27,Java,类型信息,System,Class,println,class
From: https://blog.51cto.com/u_16152603/6437646

相关文章

  • java~如何使用无符号整型
    在Java中,没有直接支持无符号整数的数据类型。Java的基本数据类型(如int、long、short、byte)都是带符号的,即它们可以表示正数和负数。.net中每种整型都有对应的无符号类型,它不会把取值范围分成正负两个区间,只在正整数范围内取值然而,你可以使用Java中的较大数据类型(如long......
  • 【JAVA】SHA加密
    1、代码packagecn.jiami;importjava.security.MessageDigest;importjava.security.NoSuchAlgorithmException;importorg.apache.commons.codec.binary.Hex;publicclassSHAUtils{protectedstaticMessageDigestmessageDigest=null;publicstaticS......
  • Java爬虫通用模板它来了
    Java爬虫在实际应用中有很多场景,例如:数据挖掘和分析、搜索引擎、电商平台、数据更新、监控与预测等行业都需要爬虫借入,那么在实际爬虫中需要注意什么?又该怎么样快速实现爬虫?下面的文章值得看一看。单线程java爬虫以下是一个基本的Java爬虫模板,使用Jsoup库进行HTML解析和网络请......
  • windows查看java进程, 终止进程命令
    查看:tasklist| findstr "java"终止:taskkill/pid20388/f/f表示强制终止......
  • Java SPI META-INF/services 详解
    目录什么是SPISPI和API的使用场景SPI的简单实现SPI原理解析DubboSPI总结什么是SPISPI(ServiceProviderInterface)是JDK提供的一套用来被第三方实现或者扩展的接口,它可以用来启用框架扩展和替换组件。SPI的作用就是为这些被扩展的API寻找服务实现。SPI和API的使用场景......
  • Java注释
    Java注释单行注释://多行注释:/**/注意:多行注释不能嵌套使用文档注释(Java特有):/***//**@author@version*/......
  • JAVA 基础面试题(框架)
    一、mybatis    首先,mybatis是一个对象关系映射(orm)框架,是为了解决面向对象与关系数据库的存在互不匹配的现象。也就是说mybatis的关注点在于对象与数据库之间的映射,mybatis会把从数据库中拿到的松散数据进行封装,使开发者直接拿到一个对象。mybatis其实就是对jdbc操作数据库......
  • Java基本概念介绍
    Java基本概念介绍Java是一种面向对象的编程语言,由JamesGosling等人在1995年开发而成。Java是跨平台的,这意味着可以在不同的操作系统上运行相同的程序。Java具有许多优点,包括安全性、可移植性、高效性和可扩展性。Java的基本结构Java程序在类中编写。每个Java程序至少需要一个类,并......
  • JAVA的springboot+vue企业客户信息反馈平台,附源码+数据库+文档+PPT
    1、项目介绍企业客户信息反馈平台能够通过互联网得到广泛的、全面的宣传,让尽可能多的用户了解和熟知企业客户信息反馈平台的便捷高效,不仅为客户提供了服务,而且也推广了自己,让更多的客户了解自己。对于企业客户信息反馈而言,若拥有自己的平台,通过平台得到更好的管理,同时提升了形象......
  • JVM内存结构&Java内存模型&Java对象模型
    1.JVM内存结构Java代码是运行在虚拟机上的,而虚拟机在执行Java程序的过程中会把管理的内存划分为若干个不同的数据区域。其中有些区域是随着虚拟机进程的启动而存在,而有些区域则依赖用户线程的启动和结束而建立和销毁。而这些区域会被划分为五个区域,具体的如下:方法区:方法区与是......