Java反射机制探秘
如何获得Class对象
1.针对每一个对象.getCalss(),可以得到对应的Class.
2.Class.forName(String),String的写法:包名.类名.就会创建包名.类名对应的那个对象
注:1.2只适用于引用类型
3.对于基本类型:封装类.TYPE代表了对应的基本类型的Class对象.Integer.TYPE对应的是int的Class对象
注:3只适用于基本类型
4.类型,Class。<第4种是通用的.>
上面的4种方法,只有方法2是动态的,只要换一个包就可以了.它具有动态潜质.所以真正意义的想体现动态编程只能使用方法2.
每种类型的Class对象只有一个,即他们的地址只有一个,但是不同类型是不同的.
所以下面的打印结果都为true.
//对与引用类型
Class c1 = "".getClass();
Class c2 = Class.forName("java.lang.String");
Class c3 = String.class;
System.out.println(c1 ==c2);//true
//对于基本类型
Class num1 = Integer.TYPE;
Class num2 = int.class;
System.out.println(num1 == num2);//true
反射获取类中的成员的相关方法
[获取构造<根据参数类型>](使用时一般用不带declared的)
Constructor<T> getConstructor(Class<?>... parameterTypes)
返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。
Constructor<?>[] getConstructors()
返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法。
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法。
Constructor<?>[] getDeclaredConstructors()
返回 Constructor 对象的一个数组,这些对象反映此 Class 对象表示的类声明的所有构造方法。
[获取属性<根据属性名>](使用时一般用是带declared的,因为属性一般都是私有的)
Field getField(String name)
返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段。
Field[] getFields()
返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段。
Field getDeclaredField(String name)
返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。
Field[] getDeclaredFields()
返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段。
[获取方法<方法名加上参数类型>](使用时一般用不带declared的)
Method getMethod(String name, Class<?>... parameterTypes)
返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。
Method[] getMethods()
返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法。
Method getDeclaredMethod(String name, Class<?>... parameterTypes)
返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。
Method[] getDeclaredMethods()
返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。
T newInstance()
创建此 Class 对象所表示的类的一个新实例。 <new Instance()可以动态的创建对象>
String toString()
将对象转换为字符串。
注意:
new Instance()调用的是无参构造,如果该类没有无参构造方法,则newInstance()会产生异常.
有declared的方法是支持私有,但是不支持继承,无declared的方法支持继承,不支持私有,且只能取出public的东西.
因此取属性的时候一般来说是带declared的,因为属性一般都是私有的,取方法时一般是不带declared的,取构造时一般也是不带declared的.
实例模拟反射获取类中的相关属性和方法
利用反射对属性赋值
Field中的方法
Object get(Object obj)
返回指定对象上此 Field 表示的字段的值。
Field f = c.getXXField(属性名);
值 = f.get(对象);
void set(Object obj, Object value)
将指定对象变量上此 Field 对象表示的字段设置为指定的新值。
f.set(对象,值);
Class<?> getType()
返回一个 Class 对象,它标识了此 Field 对象所表示字段的声明类型。
用于获取属性的类型(返回Class对象).
Class c = Student.class;
Object obj = c.newInstance(); //创建Student类的对象
Field f = c.getDeclaredField("name"); //获取name属性
f.setAccessible(true); //设置私有可以访问.
f.set(obj, "zhangsan");
System.out.println(f.get(obj)); //获取obj的name属性的值.
利用反射调用构造
对于构造真正调用是在调用newInstance()方法时.
Class c = Class.forName("com.clazz.reflect.Student");
Constructor con = c.getConstructor(); //没有执行构造,
Object cObj = c.getConstructor().newInstance();//调用无参的构造方法
Constructor conAll = c.getConstructor(int.class,String.class,int.class);
Object caobj = conAll.newInstance(1001,"zjamgs",234235);//调用含参的构造方法.
System.out.println(caobj); //打印输出
利用反射调用方法
对象.方法名(值1,2,3);
Method m = c.getMethoed(方法名,参数类型...);
m.invoke(对象,方法调用的参数 )如果底层方法所需的形参数为 0,则所提供的 args 数组长度可以为 0 或 null。
Class c = Class.forName("com.clazz.reflect.Student");
Object obj = c.newInstance(); //创建Sutdent对象.
Method msetName = c.getMethod("setName", String.class);//obj无须转换类型
msetName.invoke(obj, "zhangsan");//调用方法setName, 并传参.
Method msetId = c.getMethod("setId", int.class);
msetId.invoke(obj, 409090202);
System.out.println(obj);
反射应用实例
实体类
package org.dennisit.reflect.entity;
import java.io.Serializable;
/**
*
* User.java
*
* @version : 1.1
*
* @author : 苏若年 <a href="mailto:DennisIT@163.com">发送邮件</a>
*
* @since : 1.0 创建时间: 2013-2-26 下午01:43:56
*
* TODO : class User.java is used for ...
*
*/
public class User implements Serializable{ private String test; public void execute(String name,int age){
System.out.println("name=" + name + ",age=" + age);
}
}
反射测试类
package org.dennisit.reflect.main;
import java.lang.reflect.Field;
/**
*
* ReflectEx.java
*
* @version : 1.1
*
* @author : 苏若年 <a href="mailto:DennisIT@163.com">发送邮件</a>
*
* @since : 1.0 创建时间: 2013-2-26 下午01:46:00
*
* TODO : class ReflectEx.java is used for ...
*
*/
public class ReflectEx { public static void main(String[] args)throws Exception {
Class cls = Class.forName("org.dennisit.reflect.entity.User");
Object obj = cls.newInstance(); //创建User的对象
Field f = cls.getDeclaredField("test"); //获取test属性
f.setAccessible(true); //打开私有属性test的访问权限
f.set(obj, "zhangsan"); //为test重新复制
System.out.println(f.get(obj)); //获取obj的test属性值
//根据方法名execute获取方法
java.lang.reflect.Method m = cls.getMethod("execute", String.class, int.class);
m.invoke(obj, "dennisit",23); //调用execute方法
}
}
运行效果
zhangsan
name=dennisit,age=23
编写一个反射动态实例化类的例子
package org.dennisit.reflect.main;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Set;
/**
*
* DynamicReflect.java
*
* @version : 1.1
*
* @author : 苏若年 <a href="mailto:DennisIT@163.com">发送邮件</a>
*
* @since : 1.0 创建时间: 2013-2-26 下午01:58:12
*
* TODO : 利用反射动态实例化的例子
*
*/
public class DynamicReflect { public static Object getInstance(String className,Map<String,Object> map)throws Exception{
Class c = Class.forName(className);
Object obj = c.newInstance(); //对象对象
Set<String> keys = map.keySet(); //获取对应的所有属性
Field[] fAll = c.getDeclaredFields(); //获取类中所有属性
for(int i=0;i<fAll.length;i++){
for(String key:keys){ //循环匹配
if(fAll[i].getName().equals(key)){ //如果用户传入的属性跟获取到的类中的属性名匹配
Field f = c.getDeclaredField(key);//获取该属性
//构建setXxx()方法名
String methodName = "set" + key.substring(0,1).toUpperCase()+key.substring(1);
Method method = c.getMethod(methodName, f.getType());//根据构建的用户名获取对应的方法
method.invoke(obj, map.get(key));//方法调用
}else{
continue;
}
}
}
return obj;
}
}
接下来我们测试我们编写的动态反射实例化例子
实体类
package org.dennisit.reflect.entity;
import java.io.Serializable;
/**
*
* User.java
*
* @version : 1.1
*
* @author : 苏若年 <a href="mailto:DennisIT@163.com">发送邮件</a>
*
* @since : 1.0 创建时间: 2013-2-26 下午01:43:56
*
* TODO : 实体类
*
*/
public class User implements Serializable{ private String name;
private int age;
private String email; public User() { //必须有无参构造 } //getter() and setter() }
主测试类
package org.dennisit.reflect.main;
import java.util.HashMap;
import java.util.Map;
import org.dennisit.reflect.entity.User;
/**
*
* ReflectEx.java
*
* @version : 1.1
*
* @author : 苏若年 <a href="mailto:DennisIT@163.com">发送邮件</a>
*
* @since : 1.0 创建时间: 2013-2-26 下午01:46:00
*
* TODO : class ReflectEx.java is used for ...
*
*/
public class ReflectEx { public static void main(String[] args)throws Exception {
Class cls = Class.forName("org.dennisit.reflect.entity.User");
String className = "org.dennisit.reflect.entity.User";
Map<String,Object> map = new HashMap<String, Object>();
map.put("name", "dennisit");
map.put("age", 22);
map.put("email", "dennisit@163.com"); User user = (User)DynamicReflect.getInstance(className, map);
System.out.println(user.getName() + "," + user.getAge() + "," + user.getEmail());
}
}
程序运行结果
dennisit,22,dennisit@163.com
Java反射机制探秘的更多相关文章
- 第28章 java反射机制
java反射机制 1.类加载机制 1.1.jvm和类 运行Java程序:java 带有main方法的类名 之后java会启动jvm,并加载字节码(字节码就是一个类在内存空间的状态) 当调用java命令 ...
- Java反射机制
Java反射机制 一:什么事反射机制 简单地说,就是程序运行时能够通过反射的到类的所有信息,只需要获得类名,方法名,属性名. 二:为什么要用反射: 静态编译:在编译时确定类型,绑定对象,即通过 ...
- java基础知识(十一)java反射机制(上)
java.lang.Class类详解 java Class类详解 一.class类 Class类是java语言定义的特定类的实现,在java中每个类都有一个相应的Class对象,以便java程序运行时 ...
- java基础知识(十一)java反射机制(下)
1.什么是反射机制? java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象都能够调用他的属性和方法,这种动态获取属性和方法的功能称为java的反射机制. ...
- Java反射机制专题
·Java Reflection Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方 ...
- java反射机制深入详解
java反射机制深入详解 转自:http://www.cnblogs.com/hxsyl/archive/2013/03/23/2977593.html 一.概念 反射就是把Java的各种成分映射成 ...
- Java反射机制DOME
Java反射机制 public class TestHibernate { @Test public void TestHb(){ try { Class cs = Class.forName(&qu ...
- 反射——Java反射机制
反射概述 什么是反射? ① 反射的概念是由Smith在1982年首次提出的,主要指程序可以访问.检测和修改它本身状态或行为的一种能力. ② JAVA反射机制是在运行状态中,对应任意一个类,都能 ...
- Java反射机制可以动态修改实例中final修饰的成员变量吗?
问题:Java反射机制可以动态修改实例中final修饰的成员变量吗? 回答是分两种情况的. 1. 当final修饰的成员变量在定义的时候就初始化了值,那么java反射机制就已经不能动态修改它的值了. ...
随机推荐
- UserDefault的使用,保存小数据到本地-iOS
//保持到本地数据 NSArray *array=@[@"234",@"sdfe"]; NSUserDefaults *userDefault=[NSUserD ...
- Uinty3d 镜面反射代码
镜面反射代码 文件名MirrorReflection.cs 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 2 ...
- easyui datagrid使用(好)
加载相关js和css,因为easyui依赖jquery,所有加载easyui前要先加载jquery,否则为提示找不到datagrid <!-- 加载jquery --> <scrip ...
- Linux-remote change password (more)
1.creat managment Certification on Mangar Serverssh-keygen -t rsa2.creat client Certification on Cli ...
- javascript 容错
window.onerror=function(){ return true;} 系统有onerror报错的代码,只要重新一下就可以在javascript错误的时候返回真(true)
- HackerRank "Bike Racer"
Just for study from its editorial~ Lesson learnt: an optimized Hungarian Algorithm: Hopcroft-Karp Al ...
- 详解 “Android UI”设计官方教程
我们曾经给大家一个<MeeGo移动终端设备开发UI设计基础教程>,同时很多朋友都在寻找Android UI开发的教程,我们从Android的官方开发者博客找了一份幻灯片,介绍了一些Andr ...
- 黄聪:HtmlAgilityPack,C#实用的HTML解析类 ---- HtmlNode类
HtmlAgilityPack中的HtmlNode类与XmlNode类差不多,提供的功能也大同小异.下面来看看该类提供功能. 一.静态属性 public static Dictionary<st ...
- Shell_Oracle Erp和其他系统Interface资料传输通过Shell进行控制(案例)
2014-06-26 Created By BaoXinjian
- Form_通过Zoom客制化跳转页面功能(案例)
2012-09-08 Created By BaoXinjian