Java基础进阶——“Java反射之二——反射实例巩固”

1662阅读 0评论2012-02-16 qhw
分类:Java

1.反射调用的实体类 Service.java
  1. package jack.classloader.test;

  2. public class Service implements IService{
  3.     
  4.     public String name;
  5.     public int age;
  6.     private String description;
  7.     
  8.     public Service(){}
  9.     
  10.     public Service(String name, int age) {
  11.         super();
  12.         this.name = name;
  13.         this.age = age;
  14.     }

  15.     @Override
  16.     public void service(){
  17.         System.out.println("Jack's Local Class Loader");
  18.     }
  19.     
  20.     public void service(String name){
  21.         System.out.println("Hello,this is "+ name +" speaking...");
  22.     }

  23.     public String getName() {
  24.         return name;
  25.     }

  26.     public void setName(String name) {
  27.         this.name = name;
  28.     }

  29.     public int getAge() {
  30.         return age;
  31.     }

  32.     public void setAge(int age) {
  33.         this.age = age;
  34.     }
  35.     
  36.     public String getDescription() {
  37.         return description;
  38.     }

  39.     private void setDescription(String description) {
  40.         this.description = description;
  41.     }

  42.     public static void main(String[] args) {
  43.         System.out.println("This is main method...");
  44.     }

  45. }
2.反射主要过程及功能(注释)
  1. System.out.println("***************************构造Class实例(五种方法)************************");
  2.         /*
  3.          --运用 getClass():Object类中的方法,每个类都拥有此方法
  4.                                 String str="abc";
  5.                                 Class cl=str.getClass();

  6.          --运用 Class.getSuperclass():Class类中的方法,返回该Class的父类的Class
  7.          --运用 Class.forName()静态方法:
  8.          --运用 .Class:类名.class
  9.          --运用 primitive wrapper classes的TYPE语法: 基本类型包装类的TYPE,如:Integer.TYPE
  10.          *注意:TYPE的使用,只适合原生(基本)数据类型
  11.          */
  12.         //构造Class对象(为一个类class生成对应的Class对象)——五种方法
  13.         //Class clazz = jack.classloader.test.Service.class;//load class 1
  14.         //Class clazz = Class.forName("jack.classloader.test.Service");//load class 2
  15.         Class<?> clazz = new jack.classloader.test.Service().getClass();//load class 3
  16.         
  17.         System.out.println("***************************访实例化默认无参构造函数************************");
  18.         //实例化默认无参构造函数(Service())
  19.         Method method = clazz.getDeclaredMethod("service", new Class[]{String.class});
  20.         Object object = clazz.newInstance();
  21.         method.invoke(object, "Jack");
  22.         
  23.         System.out.println("***************************访实例化带参数构造函数************************");
  24.         //实例化带参数构造函数(Service::Service(String, int))
  25.         Class [] ptype = new Class[]{String.class,int.class};
  26.         Constructor<?> constructor = clazz.getConstructor(ptype);
  27.         Object object2 = constructor.newInstance(new Object[]{new String("Jack"),5});
  28.         
  29.         System.out.println("***************************访问公有成员方法************************");
  30.         //access public Method(Service::getName())
  31.         Method getNameMethod = clazz.getDeclaredMethod("getName", new Class[]{});
  32.         String nameString = (String)getNameMethod.invoke(object2, new Object[]{});
  33.         System.out.println("My name is : " + nameString);
  34.         
  35.         System.out.println("***************************访问私有成员方法************************");
  36.         //access private Method(Service::setDescription(String))
  37.         // getDeclaredField方法才能调用到私有成员,而getField方法调用不到
  38.         Method setDescMethod = clazz.getDeclaredMethod("setDescription", new Class[]{String.class});
  39.         setDescMethod.setAccessible(true);// 参数值为true,禁用访问控制检查,从而使得该变量可以被其他类调用
  40.         setDescMethod.invoke(object2, new Object[]{new String("Jack's Desc")});
  41.         
  42.         System.out.println("***************************访问主方法************************");
  43.         //access main method(Service::main(String[]))
  44.      Method methodMain = clazz.getDeclaredMethod("main", String[].class);
  45.      methodMain.invoke(null, new Object[]{new String[]{"12"}});/*由于兼容性问题,在JDK1.4没有引入可变参数Object...类型,所以使用数组来表示,
  46.         invoke函数接收到String数组后进行拆分,得到两个String变量,但是没有main函数接受两个String值,所以不行,但是使用Object数组就可以了 */
  47.      methodMain.invoke(null, (Object)new String[]{"12"});//还可以使用下面方法
  48.     
  49.      System.out.println("***************************访问公有成员变量************************");
  50.      //access public field(Service::name)
  51.      Field nameField = clazz.getDeclaredField("name");
  52.      String nameValue = (String)nameField.get(object2);//reflect to get field value
  53.      System.out.println("My public name value is : " + nameValue);

  54.      System.out.println("***************************访问私有成员变量************************");
  55.      /*
  56.      利用安全管理器及反射,可以在不修改源码的基础上访问私有成员,为测试带来了极大的方便。尤其是在编译期间,该方法可以顺利地通过编译。但同时该方法也
  57.      有一些缺点。第一个是性能问题,用于字段和方法接入时反射要远慢于直接代码。第二个是权限问题,有些涉及 Java 安全的程序代码并没有修改安全管理器的
  58.      权限,此时本方法失效。
  59.      */
  60.      //access private field
  61.      Field descField = clazz.getDeclaredField("description");// getDeclaredField方法才能调用到私有成员,而getField方法调用不到
  62.      descField.setAccessible(true);//参数值为true,禁用访问控制检查,从而使得该变量可以被其他类调用
  63.      String descValue = (String)descField.get(object2);
  64.      System.out.println("My private desc value is : " + descValue);
  65.         
  66.      System.out.println("***************************迭代列出所有成员变量************************");
  67.         Field[] fields = clazz.getDeclaredFields();
  68.         for(Field field : fields){
  69.             field.setAccessible(true);
  70.             System.out.print(field.getName() + " ");//变量名
  71.             System.out.print(field.getType() + " ");//变量类型
  72.             System.out.println(field.getModifiers());
  73.         }
  74.         
  75.         System.out.println("***************************迭代列出所有成员方法************************");
  76.         Method[] methods = clazz.getDeclaredMethods();
  77.         for(Method localMethod : methods){
  78.             System.out.print(localMethod.getName() + " ");//方法名
  79.             System.out.print(localMethod.getTypeParameters() + " ");//方法名
  80.             System.out.println(localMethod.getReturnType() + " ");//返回值类型
  81.         }
以上为个人学习实践,转载交流请注名出处
上一篇:Java基础进阶——“Java反射之一”
下一篇:java Coookie操作