您的位置:首页 > 编程语言 > Java开发

java反射使用实例

2017-03-26 18:43 148 查看
最近项目中用到了很多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();

    }

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息