当前位置: 首页 > news >正文

Java反射知识点学习笔记

目录

一、定义

二、获取class对象的三种方式

1、Class.forName("全类名")

2、类名.class

3、对象.getClass()

三、案例

1、获取 class 反射对象三种方式

2、利用反射获取构造方法

3、利用反射获取成员变量

4、利用反射获取成员方法


        Java反射是一种强大的编程机制,它允许程序在运行时检查和操作类、接口、字段和方法等元素。

一、定义

        Java反射是指在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性。这种动态获取信息以及动态调用对象方法的功能被称为Java语言的反射机制。(反射允许对成员变量,成员方法和构造方法的信息进行编程访问

二、获取class对象的三种方式

1、Class.forName("全类名")

源代码阶段使用 Class.forName("") 方式获取反射对象。

2、类名.class

当类名加载到了内存中,使用 类名.class 方式获取class反射对象。

3、对象.getClass()

当内存中 new 了一个类对象,处于运行阶段。则使用 对象.getClass() 方式获取反射对象。

三、案例

1、获取 class 反射对象三种方式

假设我们有 Student 对象

package com.angindem.myreflect1;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
public class Student {private String name;private int age;public Student(String name, int age) {this.name = name;this.age = age;}
}

代码案例:

package com.angindem.myreflect1;public class MyReflectDemo1 {public static void main(String[] args) throws ClassNotFoundException {/***   获取class对象的三种方式:*   1.Class.forName("全类名")*   2.类名.class*   3.对象.getClass()*/
//        1.第一种方式
//        全类名: 包名 + 类名
//        最为常用的Class sClass1 = Class.forName("com.angindem.myreflect1.Student");System.out.println(sClass1);
//        2.第二种方式
//        一般更多的是当作参数进行传递Class sClass2 = Student.class;System.out.println(sClass2);System.out.println(sClass1 == sClass2);
//        3.第三种方式
//        当我们已经有了这个类的对象时,才可以使用Student s = new Student("angindem", 18);Class sClass3 = s.getClass();System.out.println(sClass3);System.out.println(sClass1 == sClass3);}
}

2、利用反射获取构造方法

假设我们有 Student 对象

package com.angindem.myreflect2;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
public class Student {private String name;private int age;private Student(String name, int age) {this.name = name;this.age = age;}public Student() {}public Student(String name) {this.name = name;}protected Student(int age) {this.age = age;}
}

代码案例:

package com.angindem.myreflect2;import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;public class MyReflectDemo {public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {/***   Class 类中用于获取构造方法的方法*   Constructor<?>[] getConstructors()*   Constructor<?>[] getDeclaredConstructors()*   Constructor<?> getConstructor(Class<?>... parameterTypes)*   Constructor<?> getDeclaredConstructor(Class<?>... parameterTypes)**  Constructor类中用于创建对象的方法*  T newInstance(Object... initargs)*  setAccessible(boolean flag)*///        1、获取 class 字节码文件对象Class<?> clazz = Class.forName("com.angindem.myreflect2.Student");//        2、获取所有公有构造器
//        Constructor<?>[] cons = clazz.getConstructors();
//        for (Constructor<?> con : cons){
//            System.out.println(con);
//        }//        3、获取所有构造器(包括私有、受保护、默认、公有)
//        Constructor<?>[] cons = clazz.getDeclaredConstructors();
//        for (Constructor<?> con : cons){
//            System.out.println(con);
//        }//        4、获取单个的构造器Constructor<?> con1 = clazz.getDeclaredConstructor();
//        System.out.println(con1);Constructor<?> con2 = clazz.getDeclaredConstructor(String.class);
//        System.out.println(con2);Constructor<?> con3 = clazz.getDeclaredConstructor(int.class);
//        System.out.println(con3);
//Constructor<?> con4 = clazz.getDeclaredConstructor(String.class, int.class);
//        System.out.println(con4);//        获取权限修饰符
//        int modifiers = con4.getModifiers();
//        System.out.println(modifiers);//        获取参数个数,获取参数的类型
//        Parameter[] parameters = con4.getParameters();
//        for (Parameter parameter : parameters) {
//            System.out.println(parameter);
//        }//        通过反射构建对象,参数类型要符合构造函数的参数类型
//        小细节: getDeclaredConstructor 只能获取当前类中的构造器相关信息,当类中的构造器私有时,则无法进行调用
//                需要通过 setAccessible(true) 设置为 true,临时取消访问权限限制con4.setAccessible(true);   // 这种方式也称为:暴力反射Student stu = (Student) con4.newInstance("angindem", 18);System.out.println(stu);}
}

扩展:关于 Modifier 的 常量字段值

修饰符十六进制表示描述
public10x0001表示该成员(类、方法、字段等)对所有类都可见。
private20x0002表示该成员只能在定义它的类内部访问。
protected40x0004表示该成员在定义它的类、同一包中的类以及所有子类中可见。
default00x0000表示该成员在定义它的类和同一包中的类中可见(没有显式修饰符)。
abstract10240x0400表示该类是抽象类,不能被实例化。
final160x0010表示该类不能被继承,或者该方法不能被重写,或者该字段是常量。
interface5120x0200表示该类是一个接口。
static80x0008表示该字段或方法是静态的,属于类本身而不是类的实例。
transient1280x0080表示该字段在序列化时不会被序列化。
volatile640x0040表示该字段的值可能会被多个线程同时访问,每次访问都需要从主内存中读取。
synchronized320x0020表示该方法是同步的,同一时间只能被一个线程访问。
native2560x0100表示该方法是本地方法,其实现用非 Java 语言编写。

3、利用反射获取成员变量

假设我们有 Student 对象

package com.angindem.myreflect3;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
public class Student {private String name;private int age;public String gender;public Student(String name, int age, String gender) {this.name = name;this.age = age;this.gender = gender;}
}

代码案例:

package com.angindem.myreflect3;import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;public class MyReflectDemo {public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {/***   Class 类中用于获取成员变量的方法*   Field[] getFields()                返回所有公有成员变量对象的数组*   Field[] getDeclaredFields()         返回所有成员变量对象的数组*   Field getField(String name)          返回一个公有成员变量对象*   Field getDeclaredField(String name)    返回一个成员变量对象**   Field 类中用于创建对象的方法*   void set(Object obj,Object value)       为成员变量赋值*   Object get(Object obj)                  获取成员变量的值*///        1、获取 class 字节码文件对象Class<?> clazz = Class.forName("com.angindem.myreflect3.Student");//        2、获取公有的成员变量
//        Field[] fields = clazz.getFields();
//        for (Field field : fields){
//            System.out.println(field);
//        }//        3、获取所有成员变量(包括 私有的)
//        Field[] fields = clazz.getDeclaredFields();
//        for (Field field : fields){
//            System.out.println(field);
//        }//        获取单个成员的变量Field name = clazz.getDeclaredField("name");System.out.println(name);//        获取成员变量的权限修饰符int modifiers = name.getModifiers();System.out.println(modifiers);//        获取成员变量的名称String n = name.getName();System.out.println(n);//        获取成员变量的类型Class<?> type = name.getType();System.out.println(type);//        获取成员变量的值Student stu = new Student("angindem", 18, "男");name.setAccessible(true);   // 暴力反射:临时取消访问权限Object value = name.get(stu);System.out.println(value);//        修改对象里面记录的值name.set(stu, "ang");System.out.println(stu);}
}

4、利用反射获取成员方法

假设我们有 Student 对象

package com.angindem.myreflect4;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
public class Student {private String name;private int age;public Student(String name, int age) {this.name = name;this.age = age;}public void sleep(){System.out.println("sleep睡觉");}private void eat(String food){System.out.println("在吃 " + food);}
}

代码案例:

package com.angindem.myreflect4;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class MyReflectDemo1 {public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {/***   Class 类中用于获取成员方法的方法*   Method[] getMethods()                  返回所有的公有成员方法对象的数组,包括父类中的*   Method[] getDeclaredMethods()           返回所有的成员方法对象的数组,不包括父类中的*   Method getMethod(String name,Class<?>... parameterTypes)    返回一个公有成员方法对象*   Method getDeclaredMethod(String name,Class<?>... parameterTypes)  返回一个成员方法对象**   Method类中用于创建对象的方法*   Object invoke(Object obj,Object... args) 运行方法*   参数一:用 obj 对象调用该方法*   参数二:调用方法的传递的参数(如果没有就不写)*   返回值:方法的返回值(如果没有就不写)*   获取方法的修饰符*   获取方法的名字*   获取方法的形参*   获取方法的返回值*   获取方法的抛出的异常*/
//        1、获取 class 字节码文件对象Class<?> clazz = Class.forName("com.angindem.myreflect4.Student");//        2、获取里面所有的方法对象(包含父类中所有的公共方法)
//        Method[] methods = clazz.getMethods();
//        for (Method method : methods) {
//            System.out.println(method);
//        }//        3、获取里面所有的方法对象(不能获取父类的,但是可以获取本类中私有的方法)
//        Method[] methods = clazz.getDeclaredMethods();
//        for (Method method : methods) {
//            System.out.println(method);
//        }
//        获取指定的单一方法Method m = clazz.getDeclaredMethod("eat", String.class);System.out.println(m);
//        获取方法的修饰符int modifiers = m.getModifiers();System.out.println(modifiers);
//        获取方法的名字String name = m.getName();System.out.println(name);
//        获取方法的形参Class<?>[] parameterTypes = m.getParameterTypes();for (Class<?> parameterType : parameterTypes){System.out.println(parameterType);}
//        获取方法的抛出异常Class<?>[] exceptionTypes = m.getExceptionTypes();for (Class<?> exceptionType : exceptionTypes){System.out.println(exceptionType);}
//        获取方法的返回值Class<?> returnType = m.getReturnType();System.out.println(returnType);/**   Method类中用于创建对象的方法*   Object invoke(Object obj,Object... args) 运行方法*   参数一:用 obj 对象调用该方法*   参数二:调用方法的传递的参数(如果没有就不写)*   返回值:方法的返回值(如果没有就不写)*/Student s = new Student();
//        参数一s:表示方法的调用者
//        参数“汉堡包”:表示在调用方法的时候传递的实际参数m.setAccessible(true);String result = (String) m.invoke(s, "汉堡包");System.out.println(result);}
}

相关文章:

  • VS Code 安装及常用插件
  • 【计算机视觉】OpenCV实战项目-AdvancedLaneDetection 车道检测
  • NLP高频面试题(四十六)——Transformer 架构中的位置编码及其演化详解
  • RPCRT4!OSF_CCALL::ActivateCall函数分析之RPCRT4!OSF_CCALL结构中的Bindings--RPC源代码分析
  • 2025中国移动云智算大会回顾:云智变革,AI+跃迁
  • PHP开发环境搭建(Hbuider+phpstudy)
  • 数据通信学习笔记之OSPF配置命令
  • 知识图谱中医知识问答系统|养生医案综合可视化系|推荐算法|vue+flask+neo4j+mysql
  • MATLAB 程序实现了一个层次化光网络的数据传输模拟系统
  • 【Linux基础】sqlite数据库
  • 观察者模式与发布订阅模式:解耦与通信的艺术
  • SpringBoot 动态加载 Jar 包
  • 【c语言】深入理解指针2
  • Python 获取淘宝券后价接口的详细指南
  • 2025年机动车检测站授权签字人考试真题及答案
  • 【C++】map和set
  • Windows11-24h2的任务栏时间显示秒 笔记250417
  • 更强的视觉 AI!更智能的多模态助手!Qwen2.5-VL-32B-Instruct-AWQ 来袭
  • 【OSG学习笔记】Day 3: 加载你的第一个3D模型
  • Pytest 的钩子函数 (Hook Functions):定制你的测试流程 (Pytest 系列之五)
  • 讲座|为什么要不断地翻译叶芝的诗?它们为什么值得细读?
  • 铁路迎来节前出行高峰,今日全国铁路预计发送旅客1870万人次
  • 阿斯利康中国区一季度收入增5%,或面临最高800万美元新罚单
  • 国台办:台商台企有信心与国家一起打赢这场关税战
  • “即买即退”扩容提质,上海静安推出离境退税2.0版新政
  • 现场聆听总书记讲话,“00后”博士和大模型CEO都“热血沸腾”