首页 > 编程语言 >Java——反射

Java——反射

时间:2023-11-22 22:24:09浏览次数:37  
标签:反射 Java System 获取 println studentClass Class out

一、类的加载  

  当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化

  加载

    就是将class文件读入内存,并为之创建一个Class对象

    任何类被使用时系统都会建立一个Class对象

  连接

    验证 是否有正确的内部结构,并和其他类协调一致

    准备 负责为类的静态成员分配内存,并设置默认初始化值

    解析 将类的二进制数据中的符号引用替换为直接引用

  初始化

二、类初始化时机

  创建类的实例

  访问类的静态变量 ,或者为静态变量赋值

  调用类的静态方法

  使用反射方式来强制创建某个类或接口对应的java.lang.Class对象

  初始化某个类的子类

  直接使用java.exe命运来运行某个主类

三、类加载器

  负责将.class文件加载到内存中,并为之生成对应的Class对象。

  虽然我们不需要关心类加载机制,但是了解这个机制我们就能更好的理解程序的运行。

  类加载器的组成

    Bootstrap ClassLoader 根类加载器

    Extension ClassLoader 扩展类加载器

    System ClassLoader 系统类加载器

四、反射

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

  对于任意一个对象,都能够任意调用它的任意一个方法和属性;

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

 

  想要解剖一个类,必须先要获取到该类的字节码文件对象。

  而解剖使用的就是Class类中的方法。

  所以先要获取到每一个字节码文件对应的Class类型的对象

五、通过反射获取构造方法

  类中的成员:

    成员变量:Field

    构造方法:Constructor

    成员方法:Method

 

获取类的Class对象
  //方式1:在对象已经存在的前提下获取
  Student student = new Student("xiaohei",18,"anhui","nan");
  Class<? extends Student> studentClass = student.getClass();

  

  //方式2:通过类名.class的方式获取 在同步锁的场景下用的比较多
  Class<Student> studentClass2 = Student.class;
  System.out.println(studentClass2==studentClass);

 

  //方式3:最常用的方式 利用Class类中的静态方法
  //static Class<?> forName(String className) 传入的是类的路径
  Class<?> studentClass = Class.forName("com.shujia.day17.Student");


Constructor<T> getConstructor(Class<?>... parameterTypes) 只能某一个获取公共的构造方法-

返回一个 Constructor对象,该对象反映 Constructor对象表示的类的指定的公共 类函数。

 

Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 获取某一个任意权限修饰符的构造方法

 

Constructor<?>[] getDeclaredConstructors() 获取所有的任意权限修饰符的构造方法

 

使用获取到的公共的构造方法
Constructor<?> constructor = studentClass.getConstructor(String.class, int.class, String.class, String.class);
T newInstance(Object... initargs)
Object o = constructor.newInstance("xxx", 18, "xxx", "男");
System.out.println(o);

使用获取到的私有的构造方法创建对象
Constructor<?> declaredConstructor = studentClass.getDeclaredConstructor();
绕过权限校验,暴力访问
declaredConstructor.setAccessible(true);
Object o = declaredConstructor.newInstance();
System.out.println(o);

六、通过反射获取成员变量并赋值

获取类的字节码文件对象

Class<?> studentClass = Class.forName("com.shujia.day17.Student");

Field getField(String name) 只能通过变量名获取公共的成员变量----------------------------------------------
Field gender = studentClass.getField("gender");
System.out.println(gender);
Field[] getFields() 只能获取所有公共的成员变量 ---------------------------------------------
Field[] fields = studentClass.getFields();
System.out.println(Arrays.toString(fields));

Field getDeclaredField(String name) 通过变量名获取任意权限修饰符的成员变量 ------------------------
Field name = studentClass.getDeclaredField("name");
System.out.println(name);
Field[] getDeclaredFields() 获取所有成员变量 ---------------------------------------------
Field[] declaredFields = studentClass.getDeclaredFields();
System.out.println(Arrays.toString(declaredFields));

七、通过反射获取成员方法并赋值

获取类的字节码文件对象
Class<?> studentClass = Class.forName("com.shujia.day17.Student");
Method getMethod(String name, Class<?>... parameterTypes) 只能获取公共的成员方法,当前和父类的公共都可以----------------------
Method fun4 = studentClass.getMethod("fun4");
System.out.println(fun4);
Method fun5 = studentClass.getMethod("fun5", String.class);
System.out.println(fun5);
Method fun1 = studentClass.getMethod("wait");
System.out.println(fun1);
getMethods 获取当前类及其父类中的所有公共的成员方法------------------------------------------
Method[] methods = studentClass.getMethods();
System.out.println(Arrays.toString(methods));

getDeclaredMethod() 获取任意一个权限修饰符的成员方法----------------------------------------
Method fun1 = studentClass.getDeclaredMethod("fun1");
System.out.println(fun1);

getDeclaredMethods 获取当前类中的所有成员方法----------------------------------------
Method[] declaredMethods = studentClass.getDeclaredMethods();
System.out.println(Arrays.toString(declaredMethods));

 

标签:反射,Java,System,获取,println,studentClass,Class,out
From: https://www.cnblogs.com/black-rosebush/p/17850446.html

相关文章

  • Java语言基础知识全总结
    一.Java的优点1.      跨平台性。一次编译,到处运行。Java编译器会将Java代码编译成能在JVM上直接运行的字节码文件,C++会将源代码编译成可执行的二进制代码文件,所以C++执行速度快2.      纯面向对象。Java所有的代码都必须在类中书写。C++兼具面向对象和面向过程的特......
  • 【Java基础】集合之——ArrayList类
    集合集合,是一种容器,类似数组,集合大小可变ArrayList可变原理当创建ArrayList集合容器时,底层会存在一个长度为10个大小的空数组如果元素溢出,则扩容原数组1.5倍大小的新数组将原数组数据,拷贝到新数组中将新元素添加到新数组原数组变成垃圾数据由Java的垃圾处理器不定时回收......
  • Java综合-猜数字
    假设游戏者共有十人,且有10个不同的姓:张、王、李、赵、刘、于、许、金、钱、孙,魔术师将十个姓写在四张纸牌上,游戏者只需指出那几张纸上有自己的姓,魔术师就能准确的说出游戏者的姓 请编程实现:分组输出姓氏,让用户选择姓氏所在的组。给出你猜的姓氏。涉及知识点:JAVA语言的基......
  • Java——网络编程
    一、概述就是用来实现网络互连的不同计算机上运行的程序间可以进行数据交换网络模式一般是指OSI参考模型TCP/IP参考模型网络通信三要素IP地址:InetAddress网络中设备的标识,不易记忆,可用主机名......
  • 2024年面向Java程序员的20个系统和软件设计面试题
    0前言系统设计问题是编程面试的重要组成部分,如果你想取得好成绩,就必须准备。在我的网站,分享了八股面试题时,也分享了一些系统设计问题,但粉丝们一直在要求更多问题,因为这个主题的确很难掌握,需要更多练习。我自己也收集了一些从朋友和同事那里获得的面试题,但为了这篇文章和自己的准......
  • 访问不同BMC时使用不同的java版本
    因项目里的服务器较多,bmc版本不一致,总会需要java1.7,部分需要1.8.总是删除安装太麻烦了,深度着同时安装多个java版本,然后使用哪个版本时,切换一下就好了。java控制面板,java,查看,使用哪个就给哪个打对号。......
  • Java排序实战:如何高效实现电商产品排序
    在当今的数字化时代,电子商务已成为人们日常生活的重要组成部分。消费者可以在电商平台上浏览和购买来自全球的商品,这无疑为我们的生活带来了极大的便利。然而,随着电商平台的规模不断扩大,商品数量的急剧增加,如何对海量商品进行高效排序成为了电商系统开发的一大挑战。一、排序的重......
  • Java排序实战:如何高效实现电商产品排序
    在当今的数字化时代,电子商务已成为人们日常生活的重要组成部分。消费者可以在电商平台上浏览和购买来自全球的商品,这无疑为我们的生活带来了极大的便利。然而,随着电商平台的规模不断扩大,商品数量的急剧增加,如何对海量商品进行高效排序成为了电商系统开发的一大挑战。一、排序的重......
  • Java——设计模式
    一、概述设计模式是历代程序员总结出的经验二、分类创建型模式:简单工厂模式工厂方法模式单例模式:饿汉式(开发)懒汉式(面试)行为型模式结构型模式三、简单工厂模式一个工厂中可以创建很多各种各样的对象缺陷:如果有新......
  • java时间截和日期格式相互转换的方法
    1.日期格式图片展示2.时间戳图片展示 ......