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 .lang.reflect.Method;

import .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:~$ com.mldn.ReflectInvoke

China,I'm Chinese! // 通过反射可以获得类的实例,也可以获取类的方法,也可以调用类对象的方法

*/

——–调用有参方法:

package com.mldn;

import .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如何在运行时调用类实例的方法
本文地址:https://www.zhiletu.com/archives-143.html
关注公众号:智乐兔

赞赏

wechat pay微信赞赏alipay pay支付宝赞赏

上一篇
下一篇

相关文章

在线留言

你必须 登录后 才能留言!

在线客服
在线客服 X

售前: 点击这里给我发消息
售后: 点击这里给我发消息

智乐兔官微