• java反射的基础学习代码


    java反射的学习,好多东西不太理解,
    主要分析了constructor,method,field,数组和调用main函数等反射的多个方面小例子。

    主要的练习类

      1 package javaAdvanced;
      2 
      3 import java.lang.reflect.*;
      4 import java.util.Arrays;
      5 
      6 /**
      7  * 类的描述信息
      8  * 反射的练习
      9  *
     10  * @author cuiH
     11  * @since 1.5
     12  */
     13 public class ReflectTest {
     14 
     15     /**
     16      * 反射:将java中各个成分 映射到相应的java类上面
     17      * 就是说你想去到java类的一些信息,就需要用到反射。(类信息层面的控制)
     18      */
     19 
     20     public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException, ClassNotFoundException {
     21 
     22         //constructor类(构造方法的反射)
     23         Constructor constructor = String.class.getConstructor(StringBuffer.class);
     24         String strTest = (String) constructor.newInstance(new StringBuffer("cuiHuan")); //调用该方法时候也需要声明类型
     25 
     26         System.out.println(strTest.charAt(3));        //运行时刻该constructor对应的是StringBuffer, constructor在编译运行时刻进行转换,泛型进行约束
     27         /**
     28          * 作用,得到每个类的构造方法
     29          * 然后调用该方法下面的构造器
     30          * 正常情况下是:class——》constructor->new object
     31          * 使用constructor->调用 constructor,调用obj
     32          */
     33 
     34 
     35         //field类的使用(字段),反射调用字段
     36         ReflectPoint pt1 = new ReflectPoint(3, 5);
     37         Field fieldY = pt1.getClass().getField("y");         //得到字节码,得到field,field是类上的某个域,去取相应对象上的该域
     38         fieldY.get(pt1);                //去到数值
     39         System.out.println(fieldY.get(pt1));
     40 
     41         /**
     42          * result:java.lang.NoSuchFieldException 若是getFiled访问私有方法时:报错没有改域
     43          * 对于私有需要用 getDeclaredField
     44          */
     45         Field fieldX = pt1.getClass().getDeclaredField("x");
     46         fieldX.setAccessible(true);
     47         System.out.println(fieldX.get(pt1));
     48         /**
     49          * result:java.lang.IllegalAccessException  提示非法错误,可以进行去到,但是仍然无法用,
     50          * 需要暴力输出:fieldX.setAccessible(true);  强制设定为可以进入(暴力进入)
     51          */
     52 
     53         //利用反射,进行对源程序进行修改。例如修改已经打完jar包的程序。
     54         changeStringValueBToA(pt1);
     55         Field[] fieldStr = pt1.getClass().getFields();
     56         System.out.println("b变为a更改后为:");
     57         for (Field field : fieldStr) {
     58             System.out.println(field.get(pt1));
     59         }
     60 
     61 
     62         //Method 类 反射调用方法  (方法调用方法,invoke调用该方法)
     63         Method methodCharAt = String.class.getMethod("charAt", int.class);
     64         methodCharAt.invoke(strTest, 3);
     65         System.out.println(methodCharAt.invoke(strTest, 3));
     66         /**
     67          * 获取方法(踩刹车)
     68          * 调用方法(刹车调用停车的方法),面向对象的设计
     69          * 相当于获取了静态方法,静态引入
     70          * 注意jdk1.4之前没有可变参数,
     71          */
     72         System.out.println(methodCharAt.invoke(strTest, new Object[]{3}));//jdk 1.4的做法,声明一个数组来代替可变参数(原始方法)
     73 
     74 
     75         TestArguments.main(new String[]{"cuiHuan", "like", "java"});    //调用main方法,原有的静态的调用方法
     76         String className = "javaAdvanced.TestArguments";
     77         Method mainMethod = Class.forName(className).getMethod("main", String[].class);
     78         mainMethod.invoke(null, new Object[]{new String[]{"cuiHuan", "like", "java"}});
     79 
     80         //数组的反射
     81         int[] a1 = new int[]{2, 1, 3};
     82         int[] a2 = new int[4];
     83         int[][] a3 = new int[2][3];
     84         String[] a5 = new String[2];
     85         String[] a6 = new String[3];
     86         String[] a4 = new String[]{"a", "b", "c"};
     87         System.out.println("数组比较:" + (a1 == a2));         //没有赋值之前为 true  ;赋值之后为false
     88         System.out.println("String比较:" + (a5 == a6));         //没有赋值之前为 true  ;赋值之后为false
     89         System.out.println("a1字节码的名字:" + a1.getClass().getName());
     90         System.out.println("a2字节码的名字:" + a2.getClass().getName());
     91         System.out.println("数组字节码比较:" + (a1.getClass() == a2.getClass()));  //说明用的是一个字节码
     92         System.out.println("一维数组的父类的字节吗的名字:" + a1.getClass().getSuperclass().getName());  //数组的父类是obj
     93         System.out.println("二维数组的父类的字节吗的名字:" + a3.getClass().getSuperclass().getName());  //数组的父类是obj
     94         System.out.println("String的父类的字节吗的名字:" + a4.getClass().getSuperclass().getName());  //数组的父类是obj
     95 
     96         Object obj1 = a1;  //数组其实是一个对象
     97         Object obj2 = a4;
     98         Object[] obj3 = a4;  //二维数组其实是一组对象
     99         Object[] obj4 = a3;
    100         System.out.println("直接输出a1:" + a1);             //result:   直接输出a1:[I@16c9ba38        类型为I(int) 具体数值为@16c9ba38
    101         System.out.println("输出为string的a1:" + Arrays.toString(a1));             //result:输出为string的a1:[2, 1, 3]
    102         System.out.println("输出为list的a1:" + Arrays.asList(a1));           //result: 输出为list的a1:[[I@15e0be38]   证书看做了一个参数(相当于一个obj)
    103         System.out.println("直接输出数组:" + a4);            //result:直接输出数组:  [Ljava.lang.String;@95c7850
    104         System.out.println("输出为list的a1:" + Arrays.asList(a4));  //字符串可以成功转换为Llist
    105 
    106         /** http://www.cnblogs.com/sosoft/
    107          * 之前可以发现,数组的本质一个对象,二维相当于一组对象,对于asList获取的是对象的地址
    108          * 当数组或者String没有初始化之前,他们共用一个字节码。(object)
    109          *
    110          * 数组反射的应用
    111          * 现在如果要改变数组的其中一个元素
    112          */
    113         System.out.println("数组反射的应用:打印数组中的每个元素");
    114         printObject(new int[]{2, 1, 3});           //result:2  1  3
    115         printObject(new int[4]);   //result: 0  0  0  0   默认数值都是0
    116         printObject("String");     //result:String
    117 
    118 
    119     }
    120 
    121     //打印数组的函数
    122     private static void printObject(Object obj) {
    123         Class cls = obj.getClass();
    124         if (cls.isArray()) {
    125             int length = Array.getLength(obj);
    126             for (int i = 0; i < length; i++) {
    127                 System.out.print(Array.get(obj, i) + "  ");
    128             }
    129         } else {
    130             System.out.println(obj);
    131         }
    132 
    133     }
    134 
    135     //有许多String类型,将所有String中的b 变为 a
    136     private static void changeStringValueBToA(Object obj) throws IllegalAccessException {
    137         Field[] fields = obj.getClass().getFields();
    138         for (Field field : fields) {
    139             //判定是String的字节码
    140             if (field.getType() == (String.class)) {   //字节码最好不用Equals比 较,双等号比较好,因为字节码只有一个,唯一
    141                 String oldValue = (String) field.get(obj);
    142                 String newValue = oldValue.replace('b', 'a');
    143                 field.set(obj, newValue);
    144             }
    145         }
    146     }
    147 
    148 
    149 }
    150 
    151 //写一个方法,调用main方法
    152 class TestArguments {
    153     public static void main(String[] args) {
    154         for (String arg : args) {
    155             System.out.println(arg);
    156         }
    157     }
    158 }

    用到的一个java类:

     1 package javaAdvanced;
     2 
     3 /**
     4  * 类的描述信息
     5  * 反射信息的测试类
     6  * http://www.cnblogs.com/sosoft/
     7  * @author cuiH
     8  * Date: 13-12-2
     9  */
    10 public class ReflectPoint {
    11     private int x;
    12     public int y;
    13 
    14     public String str1 = "football";
    15     public String str2 = "basketball";
    16     public String str3 = "pingPang";
    17 
    18     public ReflectPoint(int x, int y) {
    19         this.x = x;
    20         this.y = y;
    21     }
    22 
    23     @Override
    24     public String toString() {
    25         return super.toString();
    26     }
    27 
    28     @Override
    29     public boolean equals(Object o) {
    30         if (this == o) return true;
    31         if (!(o instanceof ReflectPoint)) return false;
    32 
    33         ReflectPoint that = (ReflectPoint) o;
    34 
    35         if (x != that.x) return false;
    36         if (y != that.y) return false;
    37 
    38         return true;
    39     }
    40 
    41     @Override
    42     public int hashCode() {
    43         int result = x;
    44         result = 31 * result + y;
    45         return result;
    46     }
    47 }
  • 相关阅读:
    2014年5月16日
    2014年4月8日
    Qt 小技巧之“To-Do 事项”
    koa中间件实现分析
    关于计算透视投影的四条边的方法,留作备忘
    关于向量
    关于ngui协同
    关于NGUI分辨率
    动态修改NGUI UI2DSprite
    动态设置viewport的宽高
  • 原文地址:https://www.cnblogs.com/sosoft/p/3462119.html
Copyright © 2020-2023  润新知