java反射使用实例

最近项目中用到了很多java反射机制,在阅读一些jar源码的过程中也发现了好多对于反射的使用,很经典。因此对其使用做了一些梳理,讲解直接注释在代码中。代码讲解的内容为基础使用。还有一部分是在项目中的使用还在总结中。

public interface B {


}

public interface B2 {


}


public class Book implements B,B2{
private String name;
private int pageNums;
private Double price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPageNums() {
return pageNums;
}
public void setPageNums(int pageNums) {
this.pageNums = pageNums;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "name: " + this.name + "page: " + pageNums + "price: " + price;
}

}


在类中测试:

package copyTable.wu.copy.util.reflact;


import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;


import org.apache.commons.collections.MapUtils;


public class ReflactTest {
/**
 * @Description: TODO(获取类名的三种方法) 
 * @date 2017年3月23日
 */
public static void main(String[] args) {
// TODO Auto-generated method stub
getClassesBythreeWays();
getMethods();
getFields();
getInterface();
Book book = getInstance();
System.out.println(book.toString());
getInstanceAndFieldEval();
}


@SuppressWarnings("unused")
public static void getClassesBythreeWays(){
try {
/**
* 第一种方法,通过forName()方法获取
*/
Class<?> clazz = Class.forName("copyTable.wu.copy.util.reflact.Book");
System.out.println("第一种方法 :" + clazz.getName());
if(clazz == null){
System.out.println("反射失败。。。");
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/**
* 第二种方法,通过类名获取
*/
Class<?> clazz = Book.class;
System.out.println("第二种方法: "  + clazz.getName());
/**
* 第三种方法,通过getClass方法
*/
// Book book1 = new Book();
// Class<? extends Book> book = book1.getClass(); //第三种方法
Class<?> book = clazz.getClass();
System.out.println("第三种方法: "  + book.getName());
}
/**

* @Description: TODO(获取对象的所有方法名称) 
* @date 2017年3月23日
* 获取到的方法列表:
* getPageNums  setPageNums  getPrice  setPrice  getName  setName  
* (Object的方法)wait  wait  wait  equals  toString  hashCode  getClass  notify  notifyAll  
*/
public static void getMethods(){
Class<?> clazz = Book.class;
Method[] methods = clazz.getMethods();
System.out.println("\n方法列表: ");
for(Method method : methods){
System.out.print(method.getName() + "  ");
}
}

//获取构造函数 Constructor<?>[] constructors = class1.getConstructors() ;
/**
 * @Description: TODO(获取所有属性) 
 * @date 2017年3月23日
 */
public static void getFields(){
Class<?> clazz = Book.class;
/**
*getDeclaredFields()获得某个类的所有申明的字段,即包括public、private和proteced
*但是不包括父类的申明字段。
*getFields()获得某个类的所有的公共(public)的字段,包括父类。
*/
Field[] fields = clazz.getDeclaredFields();
System.out.println("\n属性列表: ");
for(Field field : fields){
System.out.print(field.getName() + " ");
}
System.out.println("\n属性的范围: ");
for(Field field : fields){
System.out.println(field);
}
}
/**
* @Description: TODO(获取接口) 
* @date 2017年3月23日
*/
public static void getInterface(){
Class<?> clazz = Book.class;
Class<?>[] interfaceList = clazz.getInterfaces(); 
System.out.println("\n接口列表");
for(Class method : interfaceList){
System.out.print(method.getName() + "  ");
}
}
/**
* @Description: TODO(获取实例) 
* @date 2017年3月23日
*/
public static Book getInstance(){
Class<?> clazz = Book.class;
try {
Object obj = clazz.newInstance();
return (Book)obj;
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
/**
* @Description: TODO(实例化并给属性赋值) 
* @date 2017年3月23日
*/
public static void getInstanceAndFieldEval(){ 
Class<?> clazz = Book.class;
try {
Book book = (Book) clazz.newInstance();


Field field = clazz.getDeclaredField("name");
//由于name属性为private私有变量,所以不能直接访问,需要关闭jdk安全检查
//打破封装  实际上setAccessible是启用和禁用访问安全检查的开关,并不是为true就能访问为false就不能访问  
            //由于JDK的安全检查耗时较多.所以通过setAccessible(true)的方式关闭安全检查就可以达到提升反射速度的目的  
field.setAccessible(true);
field.set(book, "我的书名");
System.out.println("实例化并赋值后的book:"+ book.toString()); 

Method setName = clazz.getDeclaredMethod("setName", String.class);//String.class表示该setName的参数类型
setName.setAccessible(true);
setName.invoke(book, "我通过获取setName方法后修改的书名");
System.out.println("获取setName方法后修改的book:"+ book.toString()); 

//获取实例的书名
String name = (String) field.get(book);
System.out.println("通过field获取实例的书名:"+ name); 

Method getName = clazz.getDeclaredMethod("getName");
getName.setAccessible(true);
String nameByGetNameMethod = (String) getName.invoke(book);
System.out.println("通过使用Method实例调用getName方法获取的书名:"+ nameByGetNameMethod); 

//参数是int的处理,int类型不能使用integer会报错:
Method setPageNums = clazz.getDeclaredMethod("setPageNums", int.class);
setPageNums.setAccessible(true);
setPageNums.invoke(book, 222);
Method getPageNums = clazz.getDeclaredMethod("getPageNums");
getPageNums.setAccessible(true);
Integer pageNum = (Integer) getPageNums.invoke(book);
System.out.println("pageNum: " + pageNum);

//参数是Double的处理:
Method setPrice = clazz.getDeclaredMethod("setPrice", Double.class);
setPrice.setAccessible(true);
setPrice.invoke(book, 222.222);
// Method getPageNums = clazz.getDeclaredMethod("getPageNums", Double.class);
Method getPrice = clazz.getDeclaredMethod("getPrice");
getPrice.setAccessible(true);
// Integer pageNum = (Integer) getPageNums.invoke(book, Integer);
Double price = (Double) getPrice.invoke(book);
System.out.println("price: " + price);

} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

//下文总结来自:http://www.cnblogs.com/zhaoyanjun/p/6074887.html
//Constructor getConstructor(Class[] params)     根据构造函数的参数,返回一个具体的具有public属性的构造函数
//Constructor getConstructors()     返回所有具有public属性的构造函数数组
//Constructor getDeclaredConstructor(Class[] params)     根据构造函数的参数,返回一个具体的构造函数(不分public和非public属性)
//Constructor getDeclaredConstructors()    返回该类中所有的构造函数数组(不分public和非public属性)
//-------------------------------------------------------------------------------
//Method getMethod(String name, Class[] params)    根据方法名和参数,返回一个具体的具有public属性的方法
//Method[] getMethods()    返回所有具有public属性的方法数组
//Method getDeclaredMethod(String name, Class[] params)    根据方法名和参数,返回一个具体的方法(不分public和非public属性)
//Method[] getDeclaredMethods()    返回该类中的所有的方法数组(不分public和非public属性)
//-------------------------------------------------------------------------------
//Field getField(String name)    根据变量名,返回一个具体的具有public属性的成员变量
//Field[] getFields()    返回具有public属性的成员变量的数组
//Field getDeclaredField(String name)    根据变量名,返回一个成员变量(不分public和非public属性)
//Field[] getDelcaredField()    返回所有成员变量组成的数组(不分public和非public属性)

/**
* 高级使用法
*/

    public static <T> T transMap2Bean(Map<String,Object> props,T t) {
    if(MapUtils.isEmpty(props) || t==null){
    return t;
    }
try {
for(String field : props.keySet()){
Object val=props.get(field);
try {
String methodName=setMethodName(field);
Method method=t.getClass().getMethod(methodName, new Class[] { String.class });
if(method!=null){
method.invoke(t, val);
}
} catch (Exception e) {
}  
}
} catch (Exception e) {
e.printStackTrace();
return t;
}
return t;
}
    
public static String setMethodName(String fieldName){
StringBuffer methodName = new StringBuffer("set");
fieldName = fieldName.toLowerCase();
if(fieldName.indexOf("_") == 0){
methodName.append(fieldName);
}else{
methodName.append(toUpperCaseFirstOne(fieldName));
}
return methodName.toString();
}

//首字母转大写
    public static String toUpperCaseFirstOne(String s)
    {
        if(Character.isUpperCase(s.charAt(0)))
            return s;
        else
            return (new StringBuilder()).append(Character.toUpperCase(s.charAt(0))).append(s.substring(1)).toString();
    }
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值