今天在程序中用到java反射机制时,遇到的问题记录一下:我当时遇到的问题是,我用反射getMethod()调用类方法时,发生NoSuchMethodException异常,后来上网发现getMethod()调用公共方法,不能反射调用私有方法,后来找到getDeclaredField()能够访问本类中定义的所有方法。后来用这个方法解决了我遇到的问题。我查了java api文档,其中详细说明如下:
Method getDeclaredMethod(String name, Class… parameterTypes)
返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。
Method[] getDeclaredMethods()
返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。
Method getMethod(String name, Class… parameterTypes)
返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。
Method[] getMethods()
返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法。
getDeclaredField(String name)
返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。
Field[] getDeclaredFields()
返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段,包括公共、保护、默认(包)访问和私有字段,但不包括继承的字段
private String getFieldValue(ProjectToExcelDTO dto,String [] fields) {
Class clazz = dto.getClass();
String methodName;
Method method = null;
String fieldValue = null;
StringBuffer sb = new StringBuffer();
try{
for (String fieldName : fields ){
methodName = "get" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);
method = clazz.getDeclaredMethod(methodName);
fieldValue = (String)method.invoke(dto);
fieldValue = StringUtils.trimToEmpty(fieldValue);
fieldValue = "\"" + fieldValue + "\"";
sb.append(fieldValue).append(",");
}
}catch(Exception e){
e.printStackTrace();
}
return sb.toString();
}
本篇文章为在工作中使用JAVA反射
的经验总结,也可以说是一些小技巧,以后学会新的小技巧,会不断更新。本文不准备讨论JAVA反射的机制,网上有很多,大家随便google一下就可以了。
在开始之前,我先定义一个测试类Student,代码如下:
1 package chb.test.reflect;
2
3 public class Student {
4 private int age;
5 private String name;
6 public int getAge() {
7 return age;
8 }
9 public void setAge(int age) {
10 this.age = age;
11 }
12 public String getName() {
13 return name;
14 }
15 public void setName(String name) {
16 this.name = name;
17 }
18
19 public static void hi(int age,String name){
20 System.out.println("大家好,我叫"+name+",今年"+age+"岁");
21 }
22 }
一、JAVA反射的常规使用步骤
反射调用一般分为3个步骤:
·得到要调用类的class
·得到要调用的类中的方法(Method)
·方法调用(invoke)
代码示例:
1 Class cls = Class.forName("chb.test.reflect.Student");
2 Method m = cls.getDeclaredMethod("hi",new Class[]{int.class,String.class});
3 m.invoke(cls.newInstance(),20,"chb");
二、方法调用中的参数类型
在方法调用中,参数类型必须正确,这里需要注意的是不能使用包装类替换基本类型,比如不能使用Integer.class代替int.class。
如我要调用Student的setAge方法,下面的调用是正确的
1 Class cls = Class.forName("chb.test.reflect.Student");
2 Method setMethod = cls.getDeclaredMethod("setAge",int.class);
3 setMethod.invoke(cls.newInstance(), 15);
而如果我们用Integer.class替代int.class就会出错,如:
1 Class cls = Class.forName("chb.test.reflect.Student");
2 Method setMethod = cls.getDeclaredMethod("setAge",Integer.class);
3 setMethod.invoke(cls.newInstance(), 15);
jvm会报出如下异常:
1 java.lang.NoSuchMethodException: chb.test.reflect.Student.setAge(java.lang.Integer)
2 at java.lang.Class.getDeclaredMethod(Unknown Source)
3 at chb.test.reflect.TestClass.testReflect(TestClass.java:23)
三、static方法的反射调用
static方法调用时,不必得到对象示例,如下:
1 Class cls = Class.forName("chb.test.reflect.Student");
2 Method staticMethod = cls.getDeclaredMethod("hi",int.class,String.class);
3 staticMethod.invoke(cls,20,"chb");//这里不需要newInstance
4 //staticMethod.invoke(cls.newInstance(),20,"chb");
四、private的成员变量赋值
如果直接通过反射给类的private成员变量赋值,是不允许的,这时我们可以通过setAccessible方法解决。代码示例:
1 Class cls = Class.forName("chb.test.reflect.Student");
2 Object student = cls.newInstance();//得到一个实例
3 Field field = cls.getDeclaredField("age");
4 field.set(student, 10);
5 System.out.println(field.get(student));
运行如上代码,系统会报出如下异常:
1 java.lang.IllegalAccessException: Class chb.test.reflect.TestClass can not access a member of class chb.test.reflect.Student with modifiers "private"
2 at sun.reflect.Reflection.ensureMemberAccess(Unknown Source)
3 at java.lang.reflect.Field.doSecurityCheck(Unknown Source)
4 at java.lang.reflect.Field.getFieldAccessor(Unknown Source)
5 at java.lang.reflect.Field.set(Unknown Source)
6 at chb.test.reflect.TestClass.testReflect(TestClass.java:20)
解决方法:
1 Class cls = Class.forName("chb.test.reflect.Student");
2 Object student = cls.newInstance();
3 Field field = cls.getDeclaredField("age");
4 field.setAccessible(true);//设置允许访问
5 field.set(student, 10);
6 System.out.println(field.get(student));
其实,在某些场合下(类中有get,set方法),可以先反射调用set方法,再反射调用get方法达到如上效果,代码示例:
1 Class cls = Class.forName("chb.test.reflect.Student");
2 Object student = cls.newInstance();
3
4 Method setMethod = cls.getDeclaredMethod("setAge",Integer.class);
5 setMethod.invoke(student, 15);//调用set方法
6
7 Method getMethod = cls.getDeclaredMethod("getAge");
8 System.out.println(getMethod.invoke(student));//再调用get方法
分享到:
相关推荐
### Java反射机制详解 #### 一、引言 在Java面试中,经常会出现与反射...以上内容不仅解释了Java反射机制的相关知识点,还通过示例代码进行了实践演示,希望能够帮助你在Java面试中更好地理解和运用这一重要特性。
Java反射机制是Java编程语言中的一个强大特性,它允许程序在运行时检查和操作类、接口、字段以及方法等对象。这一机制的核心在于`java.lang.Class`类和相关的API,它们提供了对类元数据的访问,使得我们能够在运行时...
Java反射机制是Java编程语言中的一个重要特性,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。在Java中,反射机制的核心类集中在java.lang.reflect包下,包括Class、Constructor、Method和...
Java反射机制是Java编程语言中的一个强大工具,它允许程序在运行时检查并操作类、接口、字段和方法等对象。在"北大青鸟java反射机制"的学习资料中,我们将会深入探讨这一核心特性。 首先,我们要理解反射的核心概念...
Java反射机制是Java语言提供的一种强大功能,它允许我们在运行时检查类、接口、字段和方法的信息,并且能够在运行时动态地创建对象和调用方法。这个机制在处理不确定类型或者需要灵活操作类的场景中非常有用。在这个...
Java反射机制是Java编程语言中的一个强大特性,它允许程序在运行时检查和操作类、接口、字段和方法的信息,甚至动态地创建对象并调用其方法。通过反射,开发者可以实现高度灵活和动态的代码,这对于框架开发、元编程...
### Java反射机制详解 #### 一、反射机制是什么 反射机制是Java编程语言的一个核心特性,它允许程序在运行时动态地获取类的信息,并且能够动态地创建对象和调用对象的方法。简单来说,反射机制使得Java程序可以...
Java反射机制是Java编程语言中的一个强大特性,它允许程序在运行时检查和操作类、接口、字段和方法等对象。这一机制对于理解和利用Java的动态性至关重要,尤其是在进行复杂系统设计、框架开发以及元数据驱动的应用中...
Java反射机制是Java编程语言中一项强大的工具,它允许程序在运行时检查和操作类、接口、对象等的内部信息。反射机制的核心在于能够在运行时动态地获取类的信息,并且可以动态调用对象的方法,创建对象,甚至修改对象...
Java反射机制是Java编程语言中的一个强大特性,它允许程序在运行时检查和操作类、接口、对象等的内部结构。通过反射,开发者可以动态地创建对象、调用方法、访问字段,甚至修改私有成员,这为实现元编程和框架设计...
Java反射机制是Java编程语言中的一个强大工具,它允许程序在运行时检查和操作类、接口、对象等的内部结构。通过反射,开发者能够在运行时动态地获取类的信息(如类名、方法名、参数类型)并调用方法,创建对象,甚至...
Java反射机制是Java编程语言中的一个核心特性,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。这一机制使得Java具备了高度的灵活性和动态性,尤其是在处理元数据、创建对象、调用方法和访问...
### Java的反射机制及其实际应用 #### 一、引言 ...总之,Java反射机制是一项强大的工具,它能够在运行时动态地获取和操作类的信息。然而,应该谨慎使用反射,避免滥用造成不必要的性能损失或安全风险。
Java反射机制是Java编程语言的核心特性之一,它赋予了程序在运行时检查和操作对象的能力。反射机制使得Java代码能够动态地获取类的信息(如类名、方法、字段),并且能够在运行时创建和调用对象的方法,这为编程带来...
Java反射机制是Java编程语言中的一个强大工具,它允许程序在运行时检查和操作类、接口、对象等的内部信息。通过反射,开发者可以动态地创建对象、调用方法、访问字段,甚至修改私有成员,这在实现元编程、插件系统、...
总的来说,Java反射机制是Java编程中不可或缺的一部分,它为程序提供了强大的动态性,但也需要开发者在使用时平衡效率和安全性。通过理解和掌握反射,开发者可以更好地利用Java平台的潜力,实现更加灵活和强大的软件...
Java反射机制是Java编程语言中的一个强大特性,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。这种能力使得Java代码能够在运行时动态地获取类的信息(如类名、方法名、参数类型等)并调用...
Java反射机制是Java编程语言中的一个强大特性,它允许程序在运行时检查和操作类、接口、字段和方法。在Java中,反射机制是通过java.lang.Class类和相关的API实现的,它为我们提供了动态访问和操作类的能力。下面将...
### JAVA反射机制详解 #### 一、JAVA反射机制概述 **反射**是在1982年由Smith首次提出的概念,指的是程序有能力访问、检测并修改其自身的状态或行为。这一概念一经提出,便迅速引起了计算机科学领域的关注,并在多...
Java反射机制是一种强大的运行时功能,使得Java能够在程序执行过程中动态地获取类的信息并操纵类的对象。这一特性极大地扩展了Java语言的能力,使其更加灵活多变。下面将详细介绍Java反射机制的主要功能及其应用场景...