Java反射机制(带应用)
1、Java的反射机制:
(1)通过
类名称.class,对基本类型也支持;
Class c = int.class;
Class c = int[ ].class;
Class c = String.class
(2)通过 对象.getClass( )方法
Class c = obj.getClass( );
(3) Class.forName( ) 通过类名称加载类,这种方法只要有类名称就可以得到Class;
Class c = Class.forName(“cn.ywq.Demo”);
示例:通过反射来创建一个对象,利用.newInstance( )方法来实现。
public class Demo1 {
@Test
public void fun1() throws Exception {
String className = "cn.ywq.User";
Class clazz = Class.forName(className);
User user = (User)clazz.newInstance();
System.out.println(user);
}
}
class User {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User [username=" + username + ", password=" + password + "]";
}
}
5、Field类的使用
Field表示类的成员变量,可以是实例变量,也可以是静态变量。
(1)获取Field对象,
获取Field对象需要使用Class对象,下面是Class类的API:
Field getField(String name):通过名字获取公有成员变量的反射对象,包含父类中声明的公有成员变量;
Field[ ] getFields():获取所有公有成员变量反射对象,包含父类中声明的公有成员变量;
Field getDeclaredField(String name):通过名字获取本类中某个成员变量,包含本类的private成员变量,但父类中声明的任何成员变量都不包含;
Field[ ] getDeclaredFields():获取本类中声明的所有成员变量,包含private成员变量,但不包含父类中声明的任何成员变量;
(2)Field类的常用方法
String getName():获取成员变量名;
Class getDeclaringClass():获取成员变量的类型;
Class getType():获取当前成员变量的类型;
Object get(Object obj):获取obj对象的成员变量的值;
void set(Object obj, Object value):设置obj对象的成员变量值为value;
示例:通过Field读写成员
User.java
public class User {
public String username;
public String password;
public User() {
}
public User(String username, String password) {
this.username = username;
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User [username=" + username + ", password=" + password + "]";
}
}
Demo1.java
public class Demo1 {
@Test
public void fun1() throws Exception {
String className = "cn.itcast.User";
Class clazz = Class.forName(className);
User user = new User("zhangSan", "123");
Field field1 = clazz.getField("username");
Field field2 = clazz.getField("password") ;
String username = (String)field1.get(user);
String password = (String)field2.get(user);
System.out.println(username + ", " + password);
field1.set(user, "liSi");
field2.set(user, "456");
System.out.println(user);
}
}
Constructor表示一个类的构造器。即构造器的反射对象!
(1)获取Constructor对象
获取Construcator对象需要使用Class对象,下面API来自Class类:
Constructor getConstructor(Class… parameterTypes):通过指定的参数类型获取公有构造器反射对象;
Constructor[ ] getConstructors( ):获取所有公有构造器对象;
Constructor getDeclaredConstructor(Class… parameterTypes):通过指定参数类型获取构造器反射对象。可以是私有构造器对象;
Constructor[ ] getDeclaredConstructors():获取所有构造器对象。包含私有构造器;
(2)Construcator类常用方法
String getName():获取构造器名;
Class getDeclaringClass():获取构造器所属的类型;
Class[ ] getParameterTypes():获取构造器的所有参数的类型;
Class[ ] getExceptionTypes():获取构造器上声明的所有异常类型;
newInstance(Object… initargs):通过构造器反射对象调用构造器。
示例:通过Construcator创建对象
User.java
public class User {
private String username;
private String password;
public User() {
}
public User(String username, String password) {
this.username = username;
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User [username=" + username + ", password=" + password + "]";
}
}
Demo1.java
public class Demo1 {
@Test
public void fun1() throws Exception {
String className = "cn.itcast.User";
Class clazz = Class.forName(className);
Constructor c = clazz.getConstructor(String.class, String.class);
User user = (User)c.newInstance("zhangSan", "123");
System.out.println(user);
}
}
(1)获取Method
获取Method需要通过Class对象,下面是Class类的API:
Method getMethod(String name, Class… parameterTypes):通过方法名和方法参数类型获取方法反射对象,包含父类中声明的公有方法,但不包含所有私有方法;
Method[ ] getMethods():获取所有公有方法,包含父类中的公有方法,但不包含任何私有方法;
Method getDeclaredMethod(String name, Class… parameterTypes):通过方法名和方法参数类型获取本类中声明的方法的反射对象,包含本类中的私有方法,但不包含父类中的任何方法;
Method[ ] getDeclaredMethods( ):获取本类中所有方法,包含本类中的私有方法,但不包含父类中的任何方法。
(2)Method常用方法
String getName( ):获取方法名;
Class getDeclaringClass( ):获取方法所属的类型;
Class[ ] getParameterTypes( ):获取方法的所有参数的类型;
Class[ ] getExceptionTypes( ):获取方法上声明的所有异常类型;
Class getReturnType( ):获取方法的返回值类型;
Object invode(Object obj, Object… args):通过方法反射对象调用方法,如果当前方法是实例方法,那么当前对象就是obj,如果当前方法是static方法,那么可以给obj传递null。args表示是方法的参数;
示例:通过Method调用方法
public class Demo1 {
@Test
public void fun1() throws Exception {
String className = "cn.ywq.User";
Class clazz = Class.forName(className);
Constructor c = clazz.getConstructor(String.class, String.class);
User user = (User)c.newInstance("zhangSan", "123");
Method method = clazz.getMethod("toString");
String result = (String)method.invoke(user);
System.out.println(result);
}
}
8、AccessibleObject的使用
AccessibleObject类是Constructor、Method、Field三个类的父类。AccessibleObject最为重要的方法如下:
boolean isAccessible( ):判断当前成员是否可访问;
voidsetAccessible(boolean
flag):设置当前成员是否可访问。
当Constructor、Method、Field为私有时,如果我们想反射操作,那么就必须先调用反射对象的setAccessible(true)方法,然后才能操作。
User.java
public class User {
private String username;
private String password;
public User() {
}
public User(String username, String password) {
this.username = username;
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User [username=" + username + ", password=" + password + "]";
}
}
注意,User类的username和password成员变量为private的,这时再通过Field来反射操作这两个成员变量就必须先通过setAccessible(true)设置后才行。
public class Demo1 {
@Test
public void fun1() throws Exception {
String className = "cn.ywq.User";
Class clazz = Class.forName(className);
User user = new User("zhangSan", "123");
Field field1 = clazz.getDeclaredField("username");
Field field2 = clazz.getDeclaredField("password");
field1.setAccessible(true);
field2.setAccessible(true);
String username = (String)field1.get(user);
String password = (String)field2.get(user);
System.out.println(username + ", " + password);
field1.set(user, "liSi");
field2.set(user, "456");
System.out.println(user);
}
}
9、Java反射机制在工厂方法模式中的使用:
工厂方法模式模式主要的作用就是创建一个对象,它是new一个对象的替代品。在所有需要生成对象的地方都可以使用。
工厂方法模式利用Java的反射机制来得到Class类,利用newInstance( )方法来创建一个对象。
通用类图如下所示:
通用源代码:
//抽象产品类
public abstract class Product {
//产品类的公共方法
public void method1(){
//业务逻辑处理
}
//抽象方法
public abstract void method2();
} //多个具体产品类
public class ConcreteProduct1 extends Product {
public void method2() {
//业务逻辑处理
}
}
public class ConcreteProduct2 extends Product {
public void method2() {
//业务逻辑处理
}
} //抽象工厂类
public abstract class Creator {
/*
* 创建一个产品对象,其输入参数类型可以自行设置
* 通常为String、Enum、Class等,当然也可以为空
*/
public abstract <T extends Product> T create Product(Class<T> c);
} //具体工厂类
public class ConcreteCreator extends Creator {
public <T extends Product> T create Product(Class<T> c){
Product product=null;
try {
product = (Product)Class.forName(c.get Name()).new Instance();
} catch (Exception e) {
//异常处理
}
return (T)product;
}
}
测试代码如下:
public class Client {
public static void main(String[] args) {
Creator creator = new ConcreteCreator();
Product product = creator.createProduct(ConcreteProduct1.class);
/*
* 继续业务处理
*/
}
}
可以看到,工厂方法模式中,在具体的工厂中使用了反射机制来创建了一个product的对象。
Java反射机制(带应用)的更多相关文章
- 一文带你了解Java反射机制
想要获取更多文章可以访问我的博客 - 代码无止境. 上周上班的时候解决一个需求,需要将一批数据导出到Excel.本来公司的中间件组已经封装好了使用POI生成Excel的工具方法,但是无奈产品的需求里面 ...
- Java反射机制DOME
Java反射机制 public class TestHibernate { @Test public void TestHb(){ try { Class cs = Class.forName(&qu ...
- Java反射机制详解
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反 ...
- Java反射机制的学习
Java反射机制是Java语言被视为准动态语言的关键性质.Java反射机制的核心就是允许在运行时通过Java Reflection APIs来取得已知名字的class类的相关信息,动态地生成此类,并调 ...
- Java反射机制深入研究
ava 反射是Java语言的一个很重要的特征,它使得Java具体了“动态性”. 在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法? ...
- 11.Java反射机制 哦对了,前面的序号来自随笔关于编程之路的思索第一篇
基本概念 在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法? 答案是肯定的. 这种动态获取类的信息以及动态调用对象的方法的功能来自于J ...
- 转!!java反射机制
Java 反射机制 基本概念 在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法? 答案是肯定的. 这种动态获取类的信息以及动态调用对象 ...
- java反射机制详解 及 Method.invoke解释
JAVA反射机制 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的信息以及动态调用对象的方法的功能称为ja ...
- Java反射机制学习
Java 反射是Java语言的一个很重要的特征,它使得Java具体了“动态性”. 在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法?答 ...
随机推荐
- fetch网络请求 get 和 post
//在React Native中,使用fetch实现网络请求 /* fetch 是一个封装程度更高的网络API, 使用了Promise* Promise 是异步编程的一种解决方案* Promise 对 ...
- 网络基础 01_OSI网际互联
1 通信概述 网络是用物理链路将各个孤立的工作站或主机相连在一起,组成数据链路,从而达到资源共享和通信的目的. 通信是人与人之间通过某种媒体进行的信息交流与传递. 网络通信是通过网络将各个孤立的设备进 ...
- 高阶篇:4.1.2.1)产品总成级别的QFDII
本章目的:介绍产品总成级别的QFDII编写方法. 1.前言 这章接QFDI和QFDII总章节. 产品总成级别的QFDII,其实就是将QFDI所得到的设计要求,接着分配给产品的第一装配层级的零部件中. ...
- 2019 CCPC-Wannafly Winter Camp Day1 (Div2, onsite)
solve:4/11 补题:6/11 A 机器人 补题:zz 这是一道分类讨论的题目,有一个规律就是如果必须要从第一个区到第二个区,那么最多转区两次(1到2一次,2到1一次),然后分类讨论即可,只要细 ...
- [转] Spark快速入门指南 – Spark安装与基础使用
[From] https://blog.csdn.net/w405722907/article/details/77943331 Spark快速入门指南 – Spark安装与基础使用 2017年09月 ...
- localStorage、sessionStorage用法总结
1.作用 1.1 共同点: 都是用来存储客户端临时信息的对象. 均只能存储字符串类型的对象(虽然规范中可以存储其他原生类型的对象,但是目前为止没有浏览器对其进行实现). 1.2 ...
- prim和kruskal算法
//邻接矩阵 int n,G[MAXV][MAXN]; int d[MAXV];//表示到树的距离 bool vis[MAXV]={false}; int prim(){ fill(d,d+MAXV, ...
- 微信小程序踩坑
微信小程序自定义属性data-xx使用注意事项 data-xx采用驼峰式命名时,数据传递打印显示(以jxsName与jxsname打印显示对比) data-xx全小写命名时,数据传递打印显示
- [转]asp:ScriptManager
概述 ScriptManager 控件管理用于 Microsoft ASP.NET AJAX 页面的客户端脚本.默认情况下,ScriptManager 控件将 Microsoft AJAX 库的脚本与 ...
- springboot实现服务器端消息推送(H5原生支持)
随着互联网的发展,传统的HTTP协议已经很难满足Web应用日益复杂的需求了.近年来,随着HTML5的诞生,WebSocket协议被提出,它实现了浏览器与服务器的全双工通信,扩展了浏览器与服务端的通信功 ...