基础知识:Java反射机制

反射机制的原理

?
?

一般来说,如果想生成一个类的对象,那么运行这个程序的JVM会去确认这个类的class对象是否已经加载。如果尚未加载,那么JVM会根据类名查找.class文件,并将其载入,一旦这个类的class对象被载入内存,它就可以被用来创建这个类的的所有对象

?
?

另外如果遇到一个未知类型的引用,(JVM?)通常会采用强制类型转换的形式来得到开发者想要的类型引用,如果执行了错误的类型转换,则会报一个ClassCastException异常

?
?

在以上两个过程中,Class类一直都在起作用,因为Class类实例包含的是一个类的全部信息,包括方法、属性、构造器等

?
?

如果不是在启动时去创建这个Class实例,而是在运行时获得这个Class类实例,那么我们就可以动态的去加载一个类,动态的调用类的方法,已经动态的去访问一个类的属性,反射机制就是为这种场景而产生的,反射机制的出发点就在于JVM会为每个类创建一个java.lang.Class类的实例,通过该对象可以获取该类的全部信息,然后通过java.lang.reflect包下的API以达到以上所述的动态需求

?
?

三种情况会导致一个Java类被加载到JVM中

?
?

Student stu=new Student();

使用该类创建对象

?
?

System.out.println(student.count)

访问该类的静态成员

?
?

Class.forName("com.Student");

使用Class类的静态方法forName方法,动态的加载一个指定类名的类

ps…JDBC导入驱动类就是一个很常用的例子

?
?

三种得到一个类Class对象的方法

?
?

Class类forName方法返回的就是一个类的对象的引用

?
?

通过类的Class属性

Class<Student> clazz=Student.class;

?
?

通过getClass方法,这个方法是从Object类继承下来的

Student stu=new Student();

Class<Student> clazz=stu.getClass();

?
?

ps…获得类的Class对象后,就可以用这个对象创建和调用和访问这个类中的各种东西了

ps…Class类对象的方法getName、getConstructor、getMethod、newInstance

?
?

Field的用法:操作类的成员变量

?
?

通过Class类的getDeclaredField方法可以获得一个Field类对象的引用,有了这个对象的引用之后,就可以调用该对象的getXXX方法,其中XXX包括int,double,byte等获得某个成员变量

?
?

通过Field对象的使用来按照某一规则比较两个对象的大小

?
?

private static FieldReflect compareReflect(FieldReflect obj1,FieldReflect obj2)

?
?

三种获得的方式,本质上是三种获得Class对象的方式

?
?

//1

Field field=obj1.getClass().getDeclaredField("age");

//2

Field field=FieldReflect.class.getDeclaredField("age");

//3

Class clazz = Class.forName("com.FieldReflect.FieldReflect");

?
?

得到Class对象之后,就可以调用getDeclaredField方法得到Field对象的引用了

?
?

Field field = clazz.getDeclaredField("age");

?
?

得到Field对象的引用之后,就可以调用getXXX方法获得某一成员变量了

?
?

Field的用法:操作类的私有成员

?
?

首先我们写一个类,类的成员变量为私有

?
?

class PrivateFieldReflectClass {

private String name;

private int age;

public PrivateFieldReflectClass(String name, int age) {

super();

this.name = name;

this.age = age;

}

}

然后我们在主类中去通过反射机制得到类的Field类

?
?

public class PrivateFieldReflectTest {

public static void main(String[] args) {

PrivateFieldReflectClass fieldReflect1 = new PrivateFieldReflectClass(

"Tong", 23);

// 访问私有变量

Class<PrivateFieldReflectClass> clazz = PrivateFieldReflectClass.class;

Field field = clazz.getDeclaredField("age");

// field.setAccessible(true);

System.out.println(field.getInt(fieldReflect1));

}

}

?
?

当我们试图去访问私有变量时,会发生错误java.lang.IllegalAccessException

如果我们想去访问私有变量,需要把Field的实例对象设置Accessible属性为true即可

?
?

Field的用法:覆盖toString方法,使其能够动态更改类对象的toString展示

?
?

需要覆盖类中的toString方法,主要思想就是用类对象的getDeclaredFields方法得到Field数组,循环遍历,得到相应的Name和Value

?
?

class DataObject{

private String name;

private int age;

private String description;

private String other;

public DataObject(String name, int age, String description, String other) {

super();

this.name = name;

this.age = age;

this.description = description;

this.other = other;

}

@Override

public String toString() {

StringBuffer sb=new StringBuffer();

Field[] fields=DataObject.class.getDeclaredFields();

for (Field field : fields) {

sb.append(field.getName());

sb.append("=");

sb.append(field.get(this));

sb.append("\n");

}

return sb.toString();

}

}

?
?

Method的用法:操作类的方法

?
?

Method类,代表的是类的方法,包括静态和非静态的,与Field类似,通过反射机制,具体来说就是通过Class类对象的getMethod方法可以获得Method类的对象,然后通过该对象额invoke方法,将类名作为参数传入该方法,即可完成方法的调用

?
?

首先类中定义两个方法

?
?

public class MethodReflect {

public void m1() {

System.out.println("method 1");

}

public void m2() {

System.out.println("method 2");

}

}

?
?

然后在main函数就可以利用反射机制获取并调用想要的方法了

反射机制的过程仍旧是先得到类的对象的引用,然后通过类对象的getDeclaredMethod方法得到方法类对象的引用,然后创建一个类的对象,然后利用方法对象的invoke方法将刚创建的类对象作为参数传入,注意,这里如果方法有参数,需要将参数列表也作为参数传入invoke中

?
?

Class clazz=MethodReflect.class;

Method method=clazz.getDeclaredMethod("m1");

MethodReflect methodReflect=new MethodReflect();

method.invoke(methodReflect);

?
?

Constructor类的用法:利用反射机制实例化一个类

?
?

一般来说,我们可以通过new关键字实例化一个类,也就是创建一个类的对象,而如何通过反射机制实例话一个类呢,其实不管是通过new关键字还是通过反射,都是去调用类的构造函数,如果是去调用无参的构造函数,我们可以使用Class的newInstance方法。如果是要用到有参的构造函数的话,我们就需要用到反射包下的Constructor类

?
?

首先也是要得到类的对象的引用

?
?

Class<Student> clazz1=Student.class;

//无参:通过newInstance

Student student1=clazz1.newInstance();

//有参:通过构造器

Constructor<Student> constructor=clazz1.getConstructor(String.class,int.class);

student1=constructor.newInstance("Tong",23);

?
?

时间: 2024-10-11 05:03:54

基础知识:Java反射机制的相关文章

Java基础知识——类装载器与反射机制

类装载器ClassLoader 类装载器就是寻找类的字节码文件,并构造出类在JVM内部表示的对象组件. 类装载器把一个类装入JVM中,要经过三步: 1.装载:查找和导入Class文件: 2.链接:执行校验.准备和解析(解析是可以选择的): 3.初始化:对类的静态变量.静态代码块执行初始化工作: 类装载工作由ClassLoader及其子类负责.JVM在运行时会产生三个ClassLoader:根装载器.ExtClassLoader(扩展类装载器)和AppClassLoader(系统类装载器). 根装

JAVA基础整理-80.Java反射机制

Java什么是反射机制?反射机制的概念 在 ORM (Object Relational Mapping 对象关系映射)中间件的实现中,运用 java 反射机制可以读取任意一个 JavaBean 的所有属性,或者给这些属性赋值. Class labelCls=label1.getClass(); //label1为 JLabel 类的对象 Java反射在类中的应用: 通过反射访问构造函数(方法) 为了能够动态获取对象构造方法的信息,首先需要通过下列方法之一创建一个 Constructor 类型的

Android学习之基础知识八—Android广播机制

一.广播机制简介 Android提供了一套完整的API,允许应用程序自由的发送和接受广播,发送广播借助于我们之前学过的:Intent,而接收广播需要借助于广播接收器(Broadcast Receiver) 广播的类型主要分为两种:标准广播和有序广播. 标准广播:一种完全异步执行的广播,在广播发出之后,所有接收器几乎在同一时刻接收到这条广播消息,因此它们之间没有任何的先后顺序可言,这种广播的效率会比较高,但是同时也意味着它无法被截断的.标准广播的工作流程图如图所示: 有序广播:一种同步执行的广播,

Android学习之基础知识八—Android广播机制实践(实现强制下线功能)

强制下线功能算是比较常见的了,很多的应用程序都具备这个功能,比如你的QQ号在别处登录了,就会将你强制挤下线.实现强制下线功能的思路比较简单,只需要在界面上弹出一个对话框,让用户无法进行任何操作,必须要点击对话框中的确定按钮,然后回到登录界面即可.下面我们就来一步一步的实现这个功能: 第一步:创建一个活动管理器ActivityCollector,用于管理所有的活动 第二步:创建所有活动的父类BaseActivity,继承AppCompatActivity 因为所有的活动都是继承该活动,所有我们在该

Java反射学习:深入学习Java反射机制

一.Java反射的理解(反射是研究框架的基础之一) Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制. 二.逐步分析 参考:https://blog.csdn.net/u012585964/article/details/52011138 1.关于Class 1.Class是一个类,一个描述类的类(也就是描述类本身),封装了描述方法的Met

java基础知识(十一)java反射机制(上)

java.lang.Class类详解 java Class类详解 一.class类 Class类是java语言定义的特定类的实现,在java中每个类都有一个相应的Class对象,以便java程序运行时系统(JVM)对所有对象进行运行时类型标识,即Class对象,JVM可以通过该对象操作相应的类(如选准正确的方法执行). Class类用于封装被装入JVM中类(类或接口)的信息(类名.类型属于class.interface.enum还是annotation),是java反射机制的基础,通过Class

java基础知识(十一)java反射机制(下)

1.什么是反射机制? java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象都能够调用他的属性和方法,这种动态获取属性和方法的功能称为java的反射机制. 也就是说,java程序可以加载一个运行时才得知名称的class,获悉该类的完整构造(但不包括methods定义),并生成其对象实体,或对其fields设值,或唤起其methods.总之,就是JVM可以在运行时加载.探知.使用编译期完全未知的classes. 2.jdk提供的反射api Java反射相

【java基础】Java反射机制

一.预先需要掌握的知识(java虚拟机)  1)java虚拟机的方法区:  java虚拟机有一个运行时数据区,这个数据区又被分为方法区,堆区和栈区,我们这里需要了解的主要是方法区.方法区的主要作用是存储被装载的类 的类型信息,当java虚拟机装载某个类型的时候,需要类装载器定位相应的class文件,然后将其读入到java虚拟机中,紧接着虚拟机提取class 中的类型信息,将这些信息存储到方法区中.这些信息主要包括: 这个类型的全限定名 这个类型的直接超类的全限定名 这个类型是类类型还是接口类型

Java知识总结:Java反射机制(用实例理解)

概念理解: 反射是指一类应用,它们能够自描述和自控制.也就是说,这类应用通过采用某种机制来 实现对自己行为的描述( self-representation )和检测( examination) ,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义. Java中的反射是一个强大的工具,他能够创建灵活的代码,这些 代码可以在运行时装配,无需在组件之间进行链接,发射允许在编写和执行时,使程序代码能够接入装载到 JVM 中的类的内部信息 .而不是源代码中选定的类协作的代码.这使发射