java反射机制(java反射机制和动态代理)

其实java反射机制的问题并不复杂,但是又很多的朋友都不太了解java反射机制和动态代理,因此呢,今天小编就来为大家分享java反射机制的一些知识,希望可以帮助到大家,下面我们一起来看看这个问题的分析吧!

在Java编程语言中,反射机制是一种强大的特性,它允许我们在运行时动态地创建对象、访问对象属性和方法。听起来是不是很神奇?别急,接下来,我们就来深入解析Java反射机制,揭开它神秘的面纱。

一、什么是Java反射机制?

反射机制指的是在运行时,程序能够获取自身或其他类的信息,并对其进行操作。简单来说,就是Java程序在运行时可以“观察”到自己的结构,就像一面镜子,反射出类的属性、方法等信息。

二、Java反射机制的作用

1. 动态创建对象:在运行时,我们可以根据类的全路径名创建对象,而无需在编译时知道具体的类名。

2. 动态调用方法:在运行时,我们可以根据类名和方法名动态调用对象的方法,而无需在编译时指定具体的方法。

3. 获取类信息:在运行时,我们可以获取类的属性、方法、构造器等信息,方便进行扩展和修改。

三、Java反射机制的应用场景

1. 框架开发:许多流行的Java框架,如Spring、Hibernate等,都大量使用了反射机制。

2. 插件开发:在插件开发中,我们需要在运行时动态加载和调用插件,反射机制正是实现这一功能的利器。

3. 代码生成:在代码生成中,我们可以根据配置文件或数据库表结构动态生成Java代码。

四、Java反射机制的基本原理

Java反射机制的核心是`Class`类和`java.lang.reflect`包。下面,我们以一个简单的例子来解释其基本原理。

“`java

public class ReflectionDemo {

public static void main(String[] args) {

try {

// 获取ReflectionDemo类的Class对象

Class clazz = Class.forName(“

java中的反射机制是什么,有什么作用啊

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

JAVA反射(放射)机制:“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。但是JAVA有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。

Java反射机制主要提供了以下功能:在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。

有时候我们说某个语言具有很强的动态性,有时候我们会区分动态和静态的不同技术与作法。我们朗朗上口动态绑定(dynamic binding)、动态链接(dynamic linking)、动态加载(dynamic loading)等。然而“动态”一词其实没有绝对而普遍适用的严格定义,有时候甚至像面向对象当初被导入编程领域一样,一人一把号,各吹各的调。

一般而言,开发者社群说到动态语言,大致认同的一个定义是:“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。

尽管在这样的定义与分类下Java不是动态语言,它却有着一个非常突出的动态相关机制:Reflection。这个字的意思是“反射、映象、倒影”,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。这种“看透class”的能力(the ability of the program to examine itself)被称为introspection(内省、内观、反省)。Reflection和introspection是常被并提的两个术语。

Java如何能够做出上述的动态特性呢?这是一个深远话题,本文对此只简单介绍一些概念。整个篇幅最主要还是介绍Reflection APIs,也就是让读者知道如何探索class的结构、如何对某个“运行时才获知名称的class”生成一份实体、为其fields设值、调用其methods。本文将谈到java.lang.Class,以及java.lang.reflect中的Method、Field、Constructor等等classes。

Java的反射机制

Java反射机制是一个非常强大的功能,在很多大型项目比如Spring,Mybatis都可以看见反射的身影。通过反射机制我们可以在运行期间获取对象的类型信息,利用这一特性我们可以实现工厂模式和代理模式等设计模式,同时也可以解决Java泛型擦除等令人苦恼的问题。下面java课程就从实际应用的角度出发,来应用一下Java的反射机制。

反射基础

p.s:本文需要读者对反射机制的API有一定程度的了解,如果之前没有接触过的话,建议先看一下官方文档的QuickStart。

在应用反射机制之前,首先我们先来看一下如何获取一个对象对应的反射类Class,在Java中我们有三种方法可以获取一个对象的反射类。

通过getClass方法

在Java中,每一个Object都有一个getClass方法,通过getClass方法我们可以获取到这个对象对应的反射类:

Strings=”ziwenxie”;

Class<?>c=s.getClass();

通过forName方法

我们也可以调用Class类的静态方法forName:

Class<?>c=Class.forName(“java.lang.String”);

使用.class

或者我们也可以直接使用.class:

Class<?>c=String.class;

获取类型信息

在文章开头我们就提到反射的一大好处就是可以允许我们在运行期间获取对象的类型信息,下面我们通过一个例子来具体看一下。

首先我们在typeinfo.interfacea包下面新建一个接口A:

packagetypeinfo.interfacea;

publicinterfaceA{voidf();}

接着我们在typeinfo.packageaccess包下面新建一个接口C,接口C继承自接口A,并且我们还另外创建了几个用于测试的方法,注意下面几个方法的权限都是不同的。

java反射机制详解

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

Class类的构造方法是private,由JVM创建。

反射是java语言的一个特性,它允程序在运行时(注意不是编译的时候)来进行自我检查并且对内部的成员进行操作。例如它允许一个java的类获取他所有的成员变量和方法并且显示出来。Java的这一能力在实际应用中也许用得不是很多,但是在其它的程序设计语言中根本就不存在这一特性。例如,Pascal、C或者 C++中就没有办法在程序中获得函数定义相关的信息。(来自Sun)

JavaBean是 reflection的实际应用之一,它能让一些工具可视化的操作软件组件。这些工具通过 reflection动态的载入并取得 Java组件(类)的属性。

反射是从1.2就有的,后面的三大框架都会用到反射机制,涉及到类”Class”,无法直接new CLass(),其对象是内存里的一份字节码.  

Class类的实例表示正在运行的 Java应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class对象。

基本的 Java类型(boolean、byte、char、short、int、long、float和 double)和关键字 void也表示为 Class对象。Class没有公共构造方法。

Class对象是在加载类时由 Java虚拟机以及通过调用类加载器中的 defineClass方法自动构造的。

Person p1= new Person();

//下面的这三种方式都可以得到字节码

CLass c1= Date.class();

p1.getClass();

//若存在则加载,否则新建,往往使用第三种,类的名字在写源程序时不需要知道,到运行时再传递过来

Class.forName(“java.lang.String”);

Class.forName()字节码已经加载到java虚拟机中,去得到字节码;java虚拟机中还没有生成字节码用类加载器进行加载,加载的字节码缓冲到虚拟机中。 

另外,大家可以关注微信公众号Java技术栈回复:JVM,获取我整理的系列JVM教程,都是干货。

考虑下面这个简单的例子,让我们看看 reflection是如何工作的。

import java.lang.reflect.*;

public class DumpMethods{

public static void main(String args[]){

try{

Class c= Class.forName(“java.util.Stack”);

Method m[]= c.getDeclaredMethods();

for(int i= 0; i< m.length; i++)

System.out.println(m[i].toString());

}

catch(Throwable e){

System.err.println(e);

}

}

}

public synchronized java.lang.Object java.util.Stack.pop()

public java.lang.Object java.util.Stack.push(java.lang.Object)

public boolean java.util.Stack.empty()

public synchronized java.lang.Object java.util.Stack.peek()

public synchronized int java.util.Stack.search(java.lang.Object)

这样就列出了java.util.Stack类的各方法名以及它们的限制符和返回类型。这个程序使用 Class.forName载入指定的类,然后调用 getDeclaredMethods来获取这个类中定义了的方法列表。java.lang.reflect.Methods是用来描述某个类中单个方法的一个类。

以下示例使用 Class对象来显示对象的类名:

void printClassName(Object obj){

System.out.println(“The class of”+ obj+

” is”+ obj.getClass().getName());

}

还可以使用一个类字面值(JLS Section 15.8.2)来获取指定类型(或 void)的 Class对象。例如:

System.out.println(“The name of class Foo is:”+Foo.class.getName());

在没有对象实例的时候,主要有两种办法。

//获得类类型的两种方式

Class cls1= Role.class;

Class cls2= Class.forName(“yui.Role”);

注意第二种方式中,forName中的参数一定是完整的类名(包名+类名),并且这个方法需要捕获异常。现在得到cls1就可以创建一个Role类的实例了,利用Class的newInstance方法相当于调用类的默认的构造器。

Object o= cls1.newInstance();

//创建一个实例

//Object o1= new Role();//与上面的方法等价

OK,关于java反射机制和java反射机制和动态代理的内容到此结束了,希望对大家有所帮助。

© 版权声明
THE END
喜欢就支持一下吧
点赞9 分享