举个简单的例子,正常情况下如果已经有一个类,则肯定可以通过类创建对象;如果现在要求通过一个对象找到类的名称,此时就要用到反射机制。
Class类的使用:
Class类允许通过一个实例化对象找到一个完整的类信息。常见的用法是:实例化对象,即可以通过一个给定的字符串(包含完整的“包.类”的路径)来实例化一个类的对象;
package com.yxf.classdemos;
class Person{
String name;
int age;
}
public class ClassDemos {
public static void main(String[] args) {
// TODO Auto-generated method stub
Class<?> c1 = null;
Class<?> c2 = null;
Class<?> c3 = null;
try {
c1 = Class.forName("com.yxf.classdemos.Person");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
c2 = new Person().getClass();
c3 = Person.class;
System.out.println("Class c1: " + c1.getName());
System.out.println("Class c2: " + c2.getName());
System.out.println("Class c3: " + c3.getName());
}
}
输出结果:
Class c1: com.yxf.classdemos.Person
Class c2: com.yxf.classdemos.Person
Class c3: com.yxf.classdemos.Person
通过反射调用类中的方法:
通过反射调用类中的方法时,需要以下两步骤:
(1)通过Class类的getMethod()方法取得一个Method对象,并设置此方法操作时所需要的参数类型;
public Method getMethod(String name,Class<?>... parameterTypes) throws NoSuchMethodException,SecurityException
Parameters:
name - 所要调用的方法的名字
parameterTypes - 形参的类型列表
(2)调用invoke(),并向此方法中传递要设置的参数。
public Object invoke(Object obj,Object... args) throws IllegalAccessException,
IllegalArgumentException,InvocationTargetException
Parameters:
obj - 该方法所在的Class对象
args - 向该方法传入的实参
通过反射操作属性
在反射机制中也可以直接通过Field类操作类中的属性,通过Field类的set()和get()方法就可以完成设置和取得属性内容的操作。
下面通过例子来说明:
package com.yxf.reflectdemos;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class ReflectDemos {
public static void main(String[] args) {
// TODO Auto-generated method stub
Class<?> c1 = null;
try {
c1 = Class.forName("com.yxf.reflectdemos.Person");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Class<?>[] interfaces = c1.getInterfaces(); //取得Person类实现的全部接口
for(int i = 0; i < interfaces.length; i++){
/**Output:
* Interface name:com.yxf.reflectdemos.China
*/
System.out.println("Interface name:" + interfaces[i].getName());
}
Class<?> superClass = c1.getSuperclass();
/**Output:
* Super class:java.lang.Object
*/
System.out.println("Super class:" + superClass.getName());
Constructor<?> con[] = c1.getConstructors();//获取Person类的constructors
/**Output:
* Construtor: public com.yxf.reflectdemos.Person(java.lang.String)
* Construtor: public com.yxf.reflectdemos.Person(java.lang.String,int)
*/
for(int i = 0; i < con.length; i++){
System.out.println("Construtor: " + con[i]);
}
Person person = null;
try {
//通过反射对Person对象进行初始化
person = (Person) con[0].newInstance("xifeng.yang");
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("--------Person:" + person);
Method[] methods = c1.getMethods();
/**
* 输出每一个方法的信息,输出的信息不仅包含了Person类的方法,也把从Object类中继承而来的方法一同进行了输出
*/
for(int i = 0; i < methods.length;i++){
//System.out.println(methods[i]);
Class<?> r = methods[i].getReturnType();
Class<?> p[] = methods[i].getParameterTypes();
int modifiers = methods[i].getModifiers();
System.out.print(Modifier.toString(modifiers) + " ");
System.out.print(r.getName() + " ");
System.out.print(methods[i].getName());
System.out.print("(");
for(int x = 0; x < p.length;x++){
System.out.print(p[x].getName() + " " + "arg " + x);
if(x < p.length -1){
System.out.print(",");
}
}
Class<?> ex[] = methods[i].getExceptionTypes();
if(ex.length > 0){
System.out.print(") throws ");
}else{
System.out.print(")");
}
for(int j = 0; j < ex.length;j++){
System.out.print(ex[j].getName());
if(j < ex.length - 1){
System.out.print(",");
}
}
System.out.println();
}
Field[] f = c1.getDeclaredFields();//取得本类的属性
for(int i = 0; i < f.length;i++){
System.out.println(f[i]);
}
Field[] publicFileds = c1.getFields(); //取得父类的公共属性
for(int i = 0; i < f.length;i++){
System.out.println(publicFileds[i]);
}
/*通过反射调用类中的方法*/
try {
Method method = c1.getMethod("sayChina");
method.invoke(con[1].newInstance("xifeng.yang",28));
Method method2 = c1.getMethod("sayHello",String.class,int.class);
method2.invoke(con[1].newInstance("xifeng.yang",28), "Chris.Yang",30);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/*通过反射操作属性*/
Field nameField = null;
Field ageField = null;
try {
Object obj = c1.newInstance();
nameField = c1.getDeclaredField("name");
ageField = c1.getDeclaredField("age");
nameField.setAccessible(true);//将name属性设置为可被外部访问的
ageField.setAccessible(true);//将age属性设置为可被外部访问的
nameField.set(obj,"Tao.Lo");
ageField.set(obj, 50);
System.out.println("---Name: " + nameField.get(obj));
System.out.println("---Age: " + ageField.get(obj));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
package com.yxf.reflectdemos;
interface China{
public static final String NATION = "China";
public static final String AUTHOR = "xifeng.yang";
public void sayChina();
public String sayHello(String name, int age);
}
public class Person implements China{
private String name;
private int age;
public Person(String name, int age){
this.name = name;
this.age = age;
}
public Person(String name){
this(name, 0);
this.name = name;
}
public Person(){
this(null,0);
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public int getAge(){
return age;
}
public void setAge(int age){
this.age = age;
}
public String toString(){
return "name: " + this.name + ", age: " + this.age;
}
@Override
public void sayChina() {
// TODO Auto-generated method stub
System.out.println("------sayChina()");
System.out.println("Author: " + AUTHOR + ", NATION: " + NATION);
}
@Override
public String sayHello(String name, int age) {
// TODO Auto-generated method stub
System.out.println("------sayHello()");
return name + ", Hello! I am " + age + "years old now!";
}
}
参考文献:
《Java开发实战经典(名师讲坛)》