反射机制在java中如何做呀?

反射机制在java中如何做呀?,第1张

首先大体介绍下反射机制:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。 举个简单的列子 import javalangreflectConstructor; import javalangreflectField; import javalangreflectMethod; public class ReflectTester { / 通过java的反射机制获取类的所有属性和方法 / public void test1() { try { Class c = ClassforName("demo1clientCustomer"); Systemoutprintln("属性:"); Field f[] = cgetDeclaredFields(); for (int i = 0; i < flength; i++) { Systemoutprintln(f[i]getName()); } Systemoutprintln("方法:"); Method m[] = cgetDeclaredMethods(); for (int i = 0; i < mlength; i++) { Systemoutprintln(m[i]toString()); } } catch (Throwable e) { Systemerrprintln(e); } } / 通过java的反射机制动态修改对象的属性 @param o / public void test2(Customer o) { try { Class c = ogetClass(); //getMethod方法第一个参数指定一个需要调用的方法名称,第二个参数是需要调用方法的参数类型列表,如无参数可以指定null,该方法返回一个方法对象 Method sAge = cgetMethod("setAge", new Class[] { intclass }); Method gAge = cgetMethod("getAge", null); Method sName = cgetMethod("setName", new Class[] { Stringclass }); //动态修改Customer对象的age Object[] args1 = { new Integer(25) }; sAgeinvoke(o, args1); //动态取得Customer对象的age Integer AGE = (Integer) gAgeinvoke(o, null); Systemoutprintln("the Customer age is: " + AGEintValue()); //动态修改Customer对象的name Object[] args2 = { new String("李四") }; sNameinvoke(o, args2); } catch (Throwable e) { Systemerrprintln(e); } } / 通过java的反射机制做一个简单对象的克隆 @param o @return / public Object test3(Customer o) { Object o2 = null; try { Class c = ogetClass(); //通过默认构造方法创建一个新的对象 o2 = cgetConstructor(new Class[] {})newInstance( new Object[] {}); Field fields[] = cgetDeclaredFields(); for (int i = 0; i < fieldslength; i++) { Field field = fields[i]; String fieldName = fieldgetName(); String firstLetter = fieldNamesubstring(0, 1)toUpperCase(); // 获得和属性对应的getXXX()方法的名字 String getMethodName = "get" + firstLetter + fieldNamesubstring(1); // 获得和属性对应的setXXX()方法的名字 String setMethodName = "set" + firstLetter + fieldNamesubstring(1); // 获得和属性对应的getXXX()方法 Method getMethod = cgetMethod(getMethodName, new Class[] {}); // 获得和属性对应的setXXX()方法 Method setMethod = cgetMethod(setMethodName, new Class[] { fieldgetType() }); // 调用原对象的getXXX()方法 Object value = getMethodinvoke(o, new Object[] {}); // 调用拷贝对象的setXXX()方法 setMethodinvoke(o2, new Object[] { value }); } } catch (Throwable e) { Systemerrprintln(e); } return o2; } public static void main(String[] args) throws Exception { ReflectTester t = new ReflectTester(); ttest1(); Customer customer = new Customer(); customersetAge(20); customersetName("张三"); Systemoutprintln("调用前name: " + customergetName()); Systemoutprintln("调用前age: " + customergetAge()); ttest2(customer); Systemoutprintln("调用后name: " + customergetName()); Systemoutprintln("调用后age: " + customergetAge()); Customer customer2 = (Customer)ttest3(customer); Systemoutprintln("克隆对象的name: " + customer2getName()); Systemoutprintln("克隆对象的age: " + customer2getAge()); } } class Customer { private long id; private String name; private int age; public Customer() { } public Customer(String name, int age) { thisname = name; thisage = age; } public long getId() { return id; } public void setId(long id) { thisid = id; } public String getName() { return name; } public void setName(String name) { thisname = name; } public int getAge() { return age; } public void setAge(int age) { thisage = age; } 你可以自己运行下看看,再修改一些看看

你可以这么写:
class BodyImpl implements Body{
//do something
public static void main(String[] args) {
Type[] interfaces = BodyImplclassgetInterfaces();
ParameterizedType firstInterface = (ParameterizedType) interfaces[0];
Class c = (Class) firstInterfacegetActualTypeArguments()[0];
Systemoutprintln(cgetName()); // prints "AtomEntry"
}
}
就得到你所要的接口参数了!

Java中要用到反射,首先就必须要获取到对应的class对象,在Java中有三种方法获取类对应的class对象。

1、通过类的class属性

2、通过类实例的getClass()方法获取

3、通过ClassforName(String className)方法获取

现在比如在package下有个类Calculator

public class Calculator{

public double add(double score1,double score2){
return score1 + score2;
}

public void print(){
Systemoutprintln("OK");
}

public static double mul(double score1,double score2){
return score1  score2;
}
}public class CalculatorTest {
public static void main(String[] args) throws Exception {
//通过类的class属性获取
Class<Calculator> clz = Calculatorclass;
//或者通过类的完整路径获取,这个方法由于不能确定传入的路径是否正确,这个方法会抛ClassNotFoundException
// Class<Calculator> clz = ClassforName("testCalculator");
//或者new一个实例,然后通过实例的getClass()方法获取
// Calculator s = new Calculator();
// Class<Calculator> clz = sgetClass();
//1 获取类中带有方法签名的mul方法,getMethod第一个参数为方法名,第二个参数为mul的参数类型数组
Method method = clzgetMethod("mul", new Class[]{doubleclass,doubleclass});
//invoke 方法的第一个参数是被调用的对象,这里是静态方法故为null,第二个参数为给将被调用的方法传入的参数
Object result = methodinvoke(null, new Object[]{20,25});
//如果方法mul是私有的private方法,按照上面的方法去调用则会产生异常NoSuchMethodException,这时必须改变其访问属性
//methodsetAccessible(true);//私有的方法通过发射可以修改其访问权限
Systemoutprintln(result);//结果为50
//2 获取类中的非静态方法
Method method_2 = clzgetMethod("add", new Class[]{doubleclass,doubleclass});
//这是实例方法必须在一个对象上执行
Object result_2 = method_2invoke(new Calculator(), new Object[]{20,25});
Systemoutprintln(result_2);//45
//3 获取没有方法签名的方法print
Method method_3 = clzgetMethod("print", new Class[]{});
Object result_3 = method_3invoke(new Calculator(), null);//result_3为null,该方法不返回结果
}
}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/13089376.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-30
下一篇 2023-05-30

发表评论

登录后才能评论

评论列表(0条)

保存