Java 反射使用大全

这篇具有很好参考价值的文章主要介绍了Java 反射使用大全。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

好多年前自己记的关于Java反射的笔记,这么些年下来,自己用到反射的时候就看这一份就够了。
但是笔记以文件形式存放不方便,所以将其放到CSDN中,也希望能给更多小伙伴带来帮助。

Class类

Java程序中的各个Java类属于同一种事物,描述这类事物的Java类名就是Class

人 -> Person
Java类 -> Class

获取各个字节码对应的实例对象

方法一 : 类名:class

Class cls1 = Person.class;

方法二 : 对象:getClass

Class cls2 = p1.getClass();

方法三 : forName

Class cls3 = Class.forName("java.lang.String");

方法四 : getClassLoader().getClass

 Class clazz = getClassLoader().getClass("java.lang.String");

.class()、getClass()、Class.forName()、getClassLoader()的区别

.class是获取声明时的类。
getClass()是获取运行时的类。
Class.forName()是通过类名来获得类。
getClassLoader()是获得类的加载器。

若字节码曾经被加载过,已经待在Java虚拟机里面了,可以直接返回,如方法一和方法二
Java虚拟机中还没有这份字节码,则用类加载器去加载,把加载的字节码缓存到虚拟机中,以后,使用这份字节码就不需要加载了,如方法三

预定义对象

9个预定义对象,8个基本类型和void

Class class1 = boolean.class;
Class class2 = int.class;
//.......
Class class3 = Void.class;

isPrimitive判断是否是基本类型

int.class.isPrimitive

isArray判断是否是数组

int[].class.isArray

获得类型

getclass().getName();

反射

反射就是把Java类中的各种成分映射成相应的Java

Field:成员变量
Method:方法
Constructor:构造方法
Package:包

Constructor

得到某个类所有的构造方法
Class.forName("java.lang.String").getConstructors();
得到某一个构造方法

根据getConstructor中的参数返回相应的构造方法

Class.forName("java.lang.String").getConstructor(StringBuffer.class);
Constructor可以干什么

获取实例对象(一个constructor可以new出很无数个实例对象)

(强制转换)constructor1.newInstance(参数要和getConstructor中的一致);

通过默认构造方法创建实例(内部会缓存实例,第二次获取就不会再创建,直接获取)

String obj = (String) Class.frName("java.lang.String").newInstance();

原版反射的步骤是 Class -> Constructor -> newInstanceClass.newInstance()直接在内部Constructor,即直接Class -> Class.newInstance()即可获得默认构造方法的实例

Field

代表某个类中的一个成员变量

Person类

public class Person {
    public String name;

    private int age;

    public int getAge() {
        return age;
    }

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

通过反射获取成员变量

Person person = new Person();
person.setAge(20);
person.name = "Heiko";
//Field fieldName = person.getClass().getField("name"); 都可以
Field fieldName = Class.forName("reflectTest.Person").getField("name");
//fieldName的值为多少?不是Heiko,因为fieldName不是对象身上的变量,而是类上,要通过field.get("实例")或getDeclaredField来获取该实例上的值
String name = (String) fieldName.get(person);
System.out.println("name:" + name);

//对于私有变量,需暴力破解
Field fieldAge = person.getClass().getDeclaredField("age"); //getDeclaredField 不管是私有还是public的,都可以获取
fieldAge.setAccessible(true); //设置可以访问 fieldAge.get("age")
int age = (int) fieldAge.get(person);
System.out.println("age:" + age);  

获取静态变量

Field filed = obj.getClass().getField(cmdFieldName);
Integer cmdValue = (Integer) filed.get(null); //获取静态变量

获得所有的成员变量

obj.getClass().getFields();

getFields和getDeclaredFields的区别

getFields() : 只能访问类中声明为公有的字段,私有的字段它无法访问,能访问从其它类继承来的公有方法
getDeclaredFields() : 能访问类中所有的字段,与public,private,protect无关,不能访问从其它类继承来的方法

比较成员变量类型

if(field.getType() == String.class)

设置值

field.set(obj,新的值);

将实例中的String类型的成员变量值的b都换成a

//将对象中的String类型的成员变量所有的字符b换为字符a
private static void exchangeCharValue(Object obj) throws Exception {
    Field[] fields = obj.getClass().getFields();
    for(Field field : fields){
		//if(field.getType().equals(String.class)){ 
        if(field.getType() == String.class){ //这里用 == 比equals更准确,字节码只有一份自己和自己比较
            String oldValue = (String)field.get(obj);
            String newValue = oldValue.replace('b', 'a');
            field.set(obj, newValue);
        }
    }
}

Method

代表某个类中的一个成员方法

method.invoke(owner, args)
  • owner:执行这个方法的对象,args:参数,可以这么理解:owner对象中带有参数args的method方法。
  • 返回值是Object,也既是该方法的返回值。
String s = "abc";  
Method methodCharAt = String.class.getMethod("charAt", int.class);
String newString =methodCharAt.invoke(s, 1);//invoke是方法身上的方法,s是执行该方法的对象(必须是实例化的对象)
System.out.println(newString); 

调用静态方法

methodCharAt.invoke(null,);

反射数组

  • 若数组的维数(一维、二维等)和数组类型都相等,那么他们的字节码是同一个
  • 代表数组的Class实例对象的getSuperClass()方法返回的父类为Object类对应的Class
  • 基本类型的一维数组可以被当做Object类型使用,不能当做Object[]类型使用
  • 非基本类型的一维数组,既可以当做Object类型使用,又可以当做Object[]类型使用

ArrayList.asList时int[]和String[]的差别

因为asList接收Object[]类型,但int[]不是Object[]类型,所以交给jdk1.5之后的asList(T...t)处理,将int[]作为一个对象处理

Arrays.asList(new int[]{1,2,3}); //打印内容为:[@hascode]
Arrays.asList(new String[]{"1","2","3"}); //打印内容为:[1,2,3]

数组的反射应用

输出数组

private static void printObject(Object obj) {
    Class clazz = obj.getClass();
    if (clazz.isArray()) { //如果是数组
        int len = Array.getLength(obj);
        for (int i = 0; i < len; i++) {
            System.out.println(Array.get(obj, i));
        }
    } else {
        System.out.println(obj);
    }
}  

调用文章来源地址https://www.toymoban.com/news/detail-727115.html

String[] array = new String[] { "1", "2", "3" };
String valueString = "test";
printObject(array);
printObject(valueString);

到了这里,关于Java 反射使用大全的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java中的反射(通过反射获取类的结构、invoke方法、获取注解)

    创建运行时类的对象是反射机制应用最多的地方。创建运行时类的对象有两种方式: 方式1:直接调用Class对象的newInstance()方法 要求: 1)类必须有一个无参数的构造器。 2)类的构造器的访问权限需要足够。 方式一的步骤 : 1)获取该类型的Class对象 2)调用Class对象的 new

    2024年02月04日
    浏览(37)
  • Java 反射浅析与使用

    加载class的方式 通过Class.forName(className) className:全类名(类包名+类名) 通过类名.class方法获取 通过对象的getClass()方法获取 获取构造函数的方法 getConstructors() 返回该类声明的所有公共构造函数 getDeclaredConstructors() 返回该类声明的所有构造函数 getConstructor(Class?… parameterTypes) 返

    2024年02月03日
    浏览(25)
  • android报java.lang.UnsatisfiedLinkError错误大全

    1、java.lang.UnsatisfiedLinkError: method:logWrite, sig:(Lcom/tencent/mars/xlog/Xlog$XLoggerInfo;Ljava/lang/String;)V 完整错误日志如下:  检查是否项目开启了混淆,导致native方法及所在类被混淆,而找不到对应的方法。 2、java.lang.UnsatisfiedLinkError: No implementation found for void org.webrtc.PeerConnectionFactory.

    2024年02月13日
    浏览(29)
  • Java重点:反射机制的使用

    目录 一、概念 二、类类 1、类类的获取方式 1)类名.Class 2)对象.getClass() 3)Class.forName() 三、反射实例化 1、调用一个公有的无参构造方法 2、调用一个公有的一个参构造方法 3、调用一个公有的两个参构造方法 4、调用一个私有的一个参构造方法 四、反射:方法调用 1、公有

    2024年02月07日
    浏览(30)
  • Java反射使用的详细介绍

    反射概述 : 反射认为类的每一个成份都是一个对象, 对于任何一个Class类,在\\\"运行的时候\\\"都可以直接得到这个类全部成分。 在运行时,可以直接得到这个类的构造器对象: Constructor 在运行时,可以直接得到这个类的成员变量对象: Field 在运行时,可以直接得到这个类的成员方法

    2024年02月05日
    浏览(30)
  • Java反射(原理剖析与使用)

    1、Java反射机制的核心是在程序运行时动态加载类并获取类的详细信息,从而操作类或对象的属性和方法。本质是JVM得到class对象之后,再通过class对象进行反编译,从而获取对象的各种信息。 2、Java属于先编译再运行的语言,程序中对象的类型在编译期就确定下来了,而当程

    2024年02月02日
    浏览(21)
  • 使用Java反射针对对象字段比较。

    在Java开发中,我们经常需要比较两个对象的字段差异,尤其是在处理数据同步、状态更新等场景中。本文介绍了如何使用Java反射和Stream API优化对象字段比较的过程。 类型检查 : 确保传入的两个对象属于同一类型,否则抛出异常。 使用Stream API : 利用Stream API和Lambda表达式简化

    2024年04月14日
    浏览(23)
  • Java 中反射的概念、作用和特点,在什么情况下使用反射及使用实例

    反射(Reflection)是 Java 的一种特性,它可以让程序在运行时获取自身的信息,并且动态地操作类或对象的属性、方法和构造器等。通过反射功能,可以让我们在不知道具体类名的情况下,依然能够实例化对象,调用方法以及设置属性。 反射的作用有以下几点: 运行时探查类

    2024年02月06日
    浏览(37)
  • gin通过反射来执行动态的方法

    在gin中,可以通过反射来执行对应的方法。下面是一个示例: 在这个示例中,我们定义了一个 UserController 结构体,并在结构体中定义了 GetUser 方法和 queryUser 方法。 GetUser 方法用于处理请求并返回用户数据, queryUser 方法用于查询用户信息。 在主函数中,我们创建了 UserCon

    2024年02月14日
    浏览(35)
  • Java 中的反射是什么?如何使用它?

    在 Java 编程中,反射是一种高级的编程技术,可以在运行时动态地获取和操作类的信息。反射使得程序可以在运行时对类进行检查和操作,而不需要在编译时知道类的完整信息。这使得程序可以更加灵活和动态地处理对象,同时也为框架和库的开发提供了更大的自由度。 反射

    2024年02月16日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包