1.反射调用的实体类 Service.java
- package jack.classloader.test;
-
-
public class Service implements IService{
-
-
public String name;
-
public int age;
-
private String description;
-
-
public Service(){}
-
-
public Service(String name, int age) {
-
super();
-
this.name = name;
-
this.age = age;
-
}
-
-
@Override
-
public void service(){
-
System.out.println("Jack's Local Class Loader");
-
}
-
-
public void service(String name){
-
System.out.println("Hello,this is "+ name +" speaking...");
-
}
-
-
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 getDescription() {
-
return description;
-
}
-
-
private void setDescription(String description) {
-
this.description = description;
-
}
-
-
public static void main(String[] args) {
-
System.out.println("This is main method...");
-
}
-
- }
2.反射主要过程及功能(注释)
- System.out.println("***************************构造Class实例(五种方法)************************");
-
/*
-
--运用 getClass():Object类中的方法,每个类都拥有此方法
-
String str="abc";
-
Class cl=str.getClass();
-
-
--运用 Class.getSuperclass():Class类中的方法,返回该Class的父类的Class
-
--运用 Class.forName()静态方法:
-
--运用 .Class:类名.class
-
--运用 primitive wrapper classes的TYPE语法: 基本类型包装类的TYPE,如:Integer.TYPE
-
*注意:TYPE的使用,只适合原生(基本)数据类型
-
*/
-
//构造Class对象(为一个类class生成对应的Class对象)——五种方法
-
//Class> clazz = jack.classloader.test.Service.class;//load class 1
-
//Class> clazz = Class.forName("jack.classloader.test.Service");//load class 2
-
Class<?> clazz = new jack.classloader.test.Service().getClass();//load class 3
-
-
System.out.println("***************************访实例化默认无参构造函数************************");
-
//实例化默认无参构造函数(Service())
-
Method method = clazz.getDeclaredMethod("service", new Class[]{String.class});
-
Object object = clazz.newInstance();
-
method.invoke(object, "Jack");
-
-
System.out.println("***************************访实例化带参数构造函数************************");
-
//实例化带参数构造函数(Service::Service(String, int))
-
Class [] ptype = new Class[]{String.class,int.class};
-
Constructor<?> constructor = clazz.getConstructor(ptype);
-
Object object2 = constructor.newInstance(new Object[]{new String("Jack"),5});
-
-
System.out.println("***************************访问公有成员方法************************");
-
//access public Method(Service::getName())
-
Method getNameMethod = clazz.getDeclaredMethod("getName", new Class[]{});
-
String nameString = (String)getNameMethod.invoke(object2, new Object[]{});
-
System.out.println("My name is : " + nameString);
-
-
System.out.println("***************************访问私有成员方法************************");
-
//access private Method(Service::setDescription(String))
-
// getDeclaredField方法才能调用到私有成员,而getField方法调用不到
-
Method setDescMethod = clazz.getDeclaredMethod("setDescription", new Class[]{String.class});
-
setDescMethod.setAccessible(true);// 参数值为true,禁用访问控制检查,从而使得该变量可以被其他类调用
-
setDescMethod.invoke(object2, new Object[]{new String("Jack's Desc")});
-
-
System.out.println("***************************访问主方法************************");
-
//access main method(Service::main(String[]))
-
Method methodMain = clazz.getDeclaredMethod("main", String[].class);
-
methodMain.invoke(null, new Object[]{new String[]{"12"}});/*由于兼容性问题,在JDK1.4没有引入可变参数Object...类型,所以使用数组来表示,
-
invoke函数接收到String数组后进行拆分,得到两个String变量,但是没有main函数接受两个String值,所以不行,但是使用Object数组就可以了 */
-
methodMain.invoke(null, (Object)new String[]{"12"});//还可以使用下面方法
-
-
System.out.println("***************************访问公有成员变量************************");
-
//access public field(Service::name)
-
Field nameField = clazz.getDeclaredField("name");
-
String nameValue = (String)nameField.get(object2);//reflect to get field value
-
System.out.println("My public name value is : " + nameValue);
-
-
System.out.println("***************************访问私有成员变量************************");
-
/*
-
利用安全管理器及反射,可以在不修改源码的基础上访问私有成员,为测试带来了极大的方便。尤其是在编译期间,该方法可以顺利地通过编译。但同时该方法也
-
有一些缺点。第一个是性能问题,用于字段和方法接入时反射要远慢于直接代码。第二个是权限问题,有些涉及 Java 安全的程序代码并没有修改安全管理器的
-
权限,此时本方法失效。
-
*/
-
//access private field
-
Field descField = clazz.getDeclaredField("description");// getDeclaredField方法才能调用到私有成员,而getField方法调用不到
-
descField.setAccessible(true);//参数值为true,禁用访问控制检查,从而使得该变量可以被其他类调用
-
String descValue = (String)descField.get(object2);
-
System.out.println("My private desc value is : " + descValue);
-
-
System.out.println("***************************迭代列出所有成员变量************************");
-
Field[] fields = clazz.getDeclaredFields();
-
for(Field field : fields){
-
field.setAccessible(true);
-
System.out.print(field.getName() + " ");//变量名
-
System.out.print(field.getType() + " ");//变量类型
-
System.out.println(field.getModifiers());
-
}
-
-
System.out.println("***************************迭代列出所有成员方法************************");
-
Method[] methods = clazz.getDeclaredMethods();
-
for(Method localMethod : methods){
-
System.out.print(localMethod.getName() + " ");//方法名
-
System.out.print(localMethod.getTypeParameters() + " ");//方法名
-
System.out.println(localMethod.getReturnType() + " ");//返回值类型
- }
以上为个人学习实践,转载交流请注名出处