java如何在运行时调用类实例的方法
java可以通过反射机制调用类的所有方法,这一切都可以在运行时实时进行。
// Class类
1.public Method getMethod(String name,
Class>… parameterTypes)// 参数表可以为空
throws NoSuchMethodException,
SecurityException;// name:获取的方法名,可变参数指定方法的参数表,也可以为空调用无参的方法;
2.public T newInstance()
throws InstantiationException,
IllegalAccessException;// 获取类的无参构造生成的实例;
// Method类:
1.public Object invoke(Object obj,
Object… args) // 可变参数表示该方法的参数,可能有也可能没有;
throws IllegalAccessException,
IllegalArgumentException,
InvocationTargetException;// 调用该方法所属于的类的某个实例中当前方法;
—调用类的无参方法:
package com.mldn;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
public class ReflectInvoke
{
public static void main(String[] args)
{
Class> c = null; // 声明Class对象
try
{
c = Class.forName(“com.mldn.Person”); // 获取T类的反射
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
Method m = null; // 声明方法类
try
{
m = c.getMethod(“sayChina”); // 获取被反射的类中的方法
}
catch (NoSuchMethodException e)
{
e.printStackTrace();
}
try
{
m.invoke(c.newInstance()); // 调用被反射类实例的方法
}
catch (InstantiationException e)
{
e.printStackTrace();
}
catch (IllegalAccessException e)
{
e.printStackTrace();
}
catch (InvocationTargetException e)
{
}
}
}
/* 这里只是通过Field类的方法打印方法的详细信息
ubuntu@xu-desktop:~$ java com.mldn.ReflectInvoke
China,I’m Chinese! // 通过反射可以获得类的实例,也可以获取类的方法,也可以调用类对象的方法
*/
——–调用有参方法:
package com.mldn;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
public class ReflectInvoke
{
public static void main(String[] args)
{
Class> c = null; // 声明Class对象
try
{
c = Class.forName(“com.mldn.T”); // 获取T类的反射
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
Method m = null; // 声明方法类
try
{
m = c.getMethod(“fun”, String.class, int.class); // 获取被反射的类中的有参方法
}
catch (NoSuchMethodException e)
{
e.printStackTrace();
}
try
{
m.invoke(c.newInstance(), “张三”, 20); // 调用被反射类实例的方法,并传递相应的参数
}
catch (InstantiationException e)
{
e.printStackTrace();
}
catch (IllegalAccessException e)
{
e.printStackTrace();
}
catch (InvocationTargetException e)
{
}
}
}
class T
{
public void fun(String name, int age)
{
System.out.println(“Hello:” + ” 姓名:” + name + ” 年龄: ” + age);
}
}
/*
ubuntu@xu-desktop:~$ java com.mldn.ReflectInvoke
Hello: 姓名:张三 年龄: 20 // 调用有参方法,和无参方法一样,只不过需要确定参数类型,并传参!
*/
———-通过反射机制调用类的setter和getter方法:
package com.mldn;
import java.lang.reflect.Method;
public class InvokeSetGet
{
public static void main(String[] args)
{
Class> c = null; // 声明Class对象
Object obj = null; // 声明obj对象
try
{
c = Class.forName(“com.mldn.Person”); // 获取Person对象的反射
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
try
{
obj = c.newInstance(); // 获取实例
}
catch (Exception e)
{
e.printStackTrace();
}
setter(obj, “name”, “张三”, String.class); // 设置name属性,调用setName方法;
setter(obj, “age”, 20, int.class);
System.out.print(“姓名:”);
getter(obj, “name”); // 获取设置的属性
System.out.print(” 年龄:”);
getter(obj, “age”);
System.out.println();
}
/*
Object obj:操作的对象
String att:操作的属性
Object value:设置属性的值
Class> type:属性的类型
*/
public static void setter(Object obj, String att, Object value, Class> type)
{
try
{
Method m = (Method)obj.getClass().getMethod(“set” + initStr(att), type); // 获取指定对象的set方法
m.invoke(obj, value); // 调用obj的set方法设置属性
}
catch (Exception e)
{
e.printStackTrace();
}
}
public static String initStr(String att)
{
String str = att.substring(0, 1).toUpperCase() + att.substring(1); // 首字母大写
return str;
}
public static void getter(Object obj, String att) // 获取obj的属性值
{
try
{
Method m = obj.getClass().getMethod(“get” + initStr(att)); // 获取对象get方法
System.out.print(m.invoke(obj)); // 调用obj实例的get方法;
}
catch (Exception e)
{}
}
}
/*
ubuntu@xu-desktop:~$ java com.mldn.InvokeSetGet
姓名:张三 年龄:20
// 反射机制 对类设计中的setter,getter方法有以上的支持,所以类设计时建议设计一系列针对属性的setter与getter;
*/
———–反射机制设置并获取类的实例域:
// Field:
1.public Object get(Object obj)
throws IllegalArgumentException,
IllegalAccessException;// 获取当前属性的基于反射类的obj对象的get方法;
2.public void set(Object obj,
Object value)
throws IllegalArgumentException,
IllegalAccessException; // 当前属性基于反射类的obj实例 的set方法;
//这种操作与类中是否定义setter、getter方法无关!
// 为保证程序的安全性,最好用类的setter,getter方法;
——实例:
package com.mldn;
import java.lang.reflect.Field;
public class FieldSetGet
{
public static void main(String[] args) throws Exception
{
Class> c = null; // 声明Class对象
Object obj = null; // 声明Object对象
c = Class.forName(“com.mldn.Person”); // 实例化Class对象
obj = c.newInstance(); // 实例化Obj
Field nameField = null; // 声明name属性域
Field ageField = null; // 声明age属性域
nameField = c.getDeclaredField(“name”); // 获取类中定义的属性name
ageField = c.getDeclaredField(“age”); // 获取类中定义的属性age
nameField.setAccessible(true); // 设置name属性外部可见性,这是对该属性进行写操作的前提
ageField.setAccessible(true); // 设置age属性外部可见性
nameField.set(obj, “张三”); // 设置obj对象的name属性
ageField.set(obj, 20); // 设置obj对象的age属性
System.out.print(“姓名:” + nameField.get(obj)); // 获取obj对象的name属性值
System.out.println(” 年龄:” + ageField.get(obj)); // 获取obj镀锡的age属性值
}
}
/*
ubuntu@xu-desktop:~$ java com.mldn.FieldSetGet
Exception in thread “main” java.lang.IllegalAccessException: Class com.mldn.FieldSetGet can not access a member of class com.mldn.Person with modifiers “private” // 说明此时反射机制可以找到最原始的Person类,但此类的属性是private的,不能为外部所见;
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:65)
at java.lang.reflect.Field.doSecurityCheck(Field.java:960)
at java.lang.reflect.Field.getFieldAccessor(Field.java:896)
at java.lang.reflect.Field.set(Field.java:657)
at com.mldn.FieldSetGet.main(FieldSetGet.java:21)
// public void setAccessible(boolean flag) // Field继承自AccessibleObject类;
throws SecurityException; 设置私有对象的外部可见性!
—–设置以后:
ubuntu@xu-desktop:~$ java com.mldn.FieldSetGet
姓名:张三 年龄:20
*/
声明: 除非转自他站(如有侵权,请联系处理)外,本文采用 BY-NC-SA 协议进行授权 | 嗅谱网
转载请注明:转自《java如何在运行时调用类实例的方法》
本文地址:http://www.xiupu.net/archives-143.html
关注公众号:
微信赞赏
支付宝赞赏