Java语言基础(七)Java 的反射机制

前言

本篇文章主要介绍了 Java 中的反射机制,如何使用反射机制以及反射的优缺点。

概念

反射是 Java 中非常重要和强大的功能特性,很多优秀的开源框架如 Spring 都是基于反射的思想实现的,那什么是反射?

Java 的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为 Java 语言的反射机制。反射被视为动态语言的关键。

——百度百科

举一个最常见的例子,当我们在程序里创建某个对象的时候,我们想要调用这个对象的某个方法,程序员很难记住所有的方法的类型、参数等信息,但是我们键入 . 时,IDE 会帮我们自动列出该对象的所有可以访问的方法和属性,如下图,这里就用到了反射的机制。

在这里插入图片描述

Java 反射机制的核心时在程序运行时动态加载类,同时获取类的所有信息,进而可以创建该类的实例、操作类的属性和方法。Java 是先编译再执行的语言,一般来说,程序中的对象在编译期已经确定了,但当程序在运行时需要动态加载以前没有用到的类就可以利用反射机制完成,不需要在编译阶段就知道运行时的对象属于哪一个类。

反射常用类

反射机制所需的类主要有 java.lang 包中的 Class 类和 java.lang.reflect 包中的 Constructor 类、Field 类、Method 类、Modifier 类和 Parameter 类。

java.lang.Class

Instances of the class Class represent classes and interfaces in a running Java application. An enum is a kind of class and an annotation is a kind of interface. Every array also belongs to a class that is reflected as a Class object that is shared by all arrays with the same element type and number of dimensions. The primitive Java types (boolean, byte, char, short, int, long, float, and double), and the keyword void are also represented as Class objects.

Class has no public constructor. Instead Class objects are constructed automatically by the Java Virtual Machine as classes are loaded and by calls to the defineClass method in the class loader.

—— Java8 API

万物皆对象,类也不例外。

Class 类是一个比较特殊的类,它是反射机制的基础,Class 类的对象表示正在运行的 Java 程序中的类或接口,也就是任何一个类被加载时,即将类的 .class文件(字节码文件)读入内存的同时,JVM 都自动为之创建一个 java.lang.Class 对象,从该 Class 对象中可以获得类的许多基本信息。

枚举是一种类,注解是一种接口。每一个数组都被映射成 Class 对象的一个类,这个类被所有具有相同元素类型和维度数的数组共享。基本的 Java 数据类型(boolean, byte, char, short, int, long, float, and double)和 void 被认为是 Class 的对象。

Class 类没有公共构造方法,其对象是 JVM 在加载类时通过调用类加载器中的 defineClass() 方法创建的,因此不能显式地创建一个 Class 对象。

常用方法 描述
public Package getPackage() 返回 Class 对象对应类的包
public static Class<?> forName(String className) 返回名称为 className 的类或接口的 Class 对象
public String getName() 以字符串的形式返回由这个类对象表示的实体(类、接口、数组类、基本类型或 void)的名称
public native Class<? super T> getSuperclass() 返回 Class 对象对应类的父类 Class 对象
public Class<?>[] getInterfaces() 返回 Class 对象对应类的所有接口
public Annotation[] getAnnotations() 以数组的形式返回该类元素上的所有注解
public Constructor getConstructor(Class<?>… parameterTypes) 返回 Class 对象对应类的指定参数列表的 public 构造方法
public Constructor<?>[] getConstructors() 返回 Class 对象对应类的所有 public 构造方法
public Constructor getDeclaredConstructor(Class<?>… parameterTypes) 返回 Class 对象对应类的指定参数列表的构造方法
public Constructor<?>[] getDeclaredConstructors() 返回 Class 对象对应类的所有构造方法
public Field getField(String name) 返回 Class 对象对应类名为 name 的 public 成员变量
public Field[] getFields() 返回 Class 对象对应类的所有 public 成员变量
public Field[] getDeclaredFields() 返回 Class 对象对应类的所有成员变量
public Method getMethod(String name, Class<?>… parameterTypes) 返回 Class 对象对应类的指定参数列表的 public 方法
public Method[] getMethods() 返回 Class 对象对应类的所有 public 方法
public Method[] getDeclaredMethods() 返回 Class 对象对应类的所有方法
java.lang.reflect.Constructor

Constructor provides information about, and access to, a single constructor for a class.

Constructor permits widening conversions to occur when matching the actual parameters to newInstance() with the underlying constructor’s formal parameters, but throws an IllegalArgumentException if a narrowing conversion would occur.

—— Java8 API

java.lang.reflect.Constructor 类是 java.lang.reflect.Executable 类的子类,用于表示类的构造方法。Constructor 类提供关于类的单个构造函数的信息和访问。

常用方法 描述
public String getName() 返回构造方法的名称
public T newInstance(Object … initargs) 构造一个指定参数列表的对象
public void setAccessible(boolean flag) 设置构造方法的访问权限

public void setAccessible(boolean flag) 继承自 AccessibleObject 类,使用该方法可以设置对象的访问控制权限。

如果构造方法访问控制权限为 private ,默认是不允许使用 newInstance 方法创建对象的,如果将参数设置为 true 并执行该方法,此时可以创建构造方法控制权限为 private 的对象。

java.lang.reflect.Field

A Field provides information about, and dynamic access to, a single field of a class or an interface. The reflected field may be a class (static) field or an instance field.

A Field permits widening conversions to occur during a get or set access operation, but throws an IllegalArgumentException if a narrowing conversion would occur.

—— Java8 API

java.lang.reflect.Field 类用于封装成员变量信息。Field 类提供关于类或接口的单个属性的动态访问,反射的属性可以是类(静态)或者接口的属性。

常用方法 描述
public String getName() 返回成员变量名称
public Object get(Object obj) 获取成员变量的值
public xxx getXxx(Object obj) 获取成员变量的值,xxx 表示基本数据类型
public void set(Object obj, Object value) 设置成员变量的值
public void setXxx(Object obj, xxx x) 设置成员变量的值,xxx 表示基本数据类型,x 表示具体值
public Class<?> getType() 返回成员变量类型
java.lang.reflect.Method

A Method provides information about, and access to, a single method on a class or interface. The reflected method may be a class method or an instance method (including an abstract method).

A Method permits widening conversions to occur when matching the actual parameters to invoke with the underlying method’s formal parameters, but it throws an IllegalArgumentException if a narrowing conversion would occur.

—— Java8 API

java.lang.reflect.Method 类是 java.lang.reflect.Executable 类的子类,用于封装成员方法的信息。Method 类提供

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值