最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java高級特性之反射機(jī)制實例詳解

 更新時間:2018年08月31日 08:43:32   作者:white_fisher  
這篇文章主要介紹了Java高級特性之反射機(jī)制,結(jié)合實例形式詳細(xì)分析了Java反射機(jī)制原理、功能、使用方法及相關(guān)操作注意事項,需要的朋友可以參考下

本文實例講述了Java高級特性之反射機(jī)制。分享給大家供大家參考,具體如下:

老規(guī)矩我們還是先提出幾個問題,一門技術(shù)必然要能解決一定的問題,才有去學(xué)習(xí)掌握它的價值

  • 一、 什么是反射?
  • 二、反射能做什么?

一、 什么是反射?

用在Java身上指的是我們可以于運行時加載、探知、使用編譯期間完全未知的classes。換句話說,Java程序可以加載一個運行時才得知名稱的class,獲悉其完整構(gòu)造(但不包括methods定義),并生成其對象實體、或?qū)ζ鋐ields設(shè)值、或喚起其methods

如果你是一個Android Developer,前輩們都會教導(dǎo)你盡量少用反射,效率太低,太慢?!吧洹甭铮涞奶炀筒缓昧?,所以反射雖然慢點,但是偶爾射一下還是很”爽”的。

二、反射能做什么?

1、新建類的實例

我們知道所有的類都繼承子頂級父類Object,而Object中有hashCode()、equals()、clone()、toString()、getClass()等。其中getClass()返回一個Class 對象。我們這里就需要使用的Class對象,注意C是大寫,我們可以通過一下方式來獲取Class對象

  • 1.Class.forName("類名字符串") (注意:類名字符串必須是全稱,包名+類名)
  • 2.類名.class
  • 3.實例對象.getClass()

在Class類中有一個非常重要的方法

public T newInstance() throws InstantiationException, IllegalAccessException {
    return newInstanceImpl();
}
private native T newInstanceImpl() throws IllegalAccessException, InstantiationException;

查看Api可以看到調(diào)用newInstace方法可以返回當(dāng)前class對應(yīng)的實例對象。接下來看一個小的Demo

public class Reflection {
  public static void main(String[] args) {
    // 普通創(chuàng)建類的實例
    People p1 = new People();
    System.out.println(p1.getName());
    // 利用反射獲取類的實例
    Class clazz = People.class;
    // 常用方式,注意括號中需要放類的全路徑名
    // Class clazz = Class.forName("reflection.People");
    // Class clazz = p1.getClass();
    try {
      People p2 = (People) clazz.newInstance();
      System.out.println(p2.getName());
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}
class People {
  private String name = "張三";
  private int age;
  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;
  }
}

輸入結(jié)果:

張三
張三

2、獲取成員變量和方法

在講之前我們先來看這樣一個小按理,JSON數(shù)據(jù)轉(zhuǎn)JavaBaen對象,在不用解析庫的情況下,一般我們會這樣做

private void analysisDate(JSONObject response) throws JSONException {
    int announceid = response.getInt("announceid");
    String title = response.getString("title");
    String hits = response.getString("hits");
    String addtime = response.getString("addtime");
    NewsNotifyItem newsNotifyItem = new NewsNotifyItem(announceid,
        title, hits, addtime);
  }
}

每當(dāng)我們需要解析額時候,都需要根據(jù)不同javabean來進(jìn)行相應(yīng)的解析,我們每次進(jìn)行的操作都是一樣的,只是解析的數(shù)據(jù)不同而已,結(jié)合上篇帖子講到的泛型,這里我們就可以再利用反射來自己做一個Json解析工具

下面 是我寫的一個JsonObject對象轉(zhuǎn)JavaBean的一個工具類,需要注意的是,JSON的key需要和字段名保持一致,先說下思路

①首先通過反射獲取JavaBean中的所有字段值的名稱
②拼接出set方法
③由于字段名和Json的key值相同,利用自動名獲取Json中的值并填充的實例對象中

public class Json2BeanUtils {
  public static <T> T jsonToBean(JSONObject response, Class<T> clazz) {
    try {
      // 創(chuàng)建類的實例
      Object object = Class.forName(clazz.getName()).newInstance();
      // 獲取類中的所有成員變量
      Field[] fields = object.getClass().getDeclaredFields();
      for (int i = 0; i < fields.length; i++) {
        //設(shè)置權(quán)限
        fields[i].setAccessible(true);
        // 獲取字段的名稱
        String fieldName = fields[i].getName();
        // 過濾掉UID
        if (fieldName.endsWith("serialVersionUID")) {
          continue;
        }
        // 獲取字段的類型
        String fieldType = fields[i].getGenericType().toString();
        // 拼接出JavaBean中的set方法 這里有一個坑 后面講解
        String methodName = "set"
            + fieldName.substring(0, 1).toUpperCase()
            + fieldName.substring(1);
        try {
          // 判斷變量類型
          if (fieldType.endsWith("class java.lang.String")) {
            // 獲取到set方法
            Method m = object.getClass().getMethod(methodName,
                String.class);
            String value = null;
            try {
              // 從JsonObj中取出相應(yīng)的值
              value = response.getString(fieldName);
            } catch (Exception e) {
              e.printStackTrace();
              value = "";
            }
            if (TextUtils.isEmpty(value)) {
              value = "";
            } else if (value.endsWith("null")) {
              value = "";
            }
            // 賦值
            m.invoke(object, value);
          } else if (fieldType.endsWith("int")
              || fieldType.endsWith("class java.lang.Integer")) {
            // int 類型
            System.out.println();
            Method m = object.getClass().getMethod(methodName,
                int.class);
            int value = -1;
            try {
              value = response.getInt(fieldName);
            } catch (Exception e) {
              e.printStackTrace();
              value = -1;
            }
            m.invoke(object, value);
          } else if (fieldType.endsWith("boolean")
              || fieldType
                  .endsWith("fieldType:class java.lang.Boolean")) {
            // boolean 類型
            Method m = object.getClass().getMethod(methodName,
                boolean.class);
            boolean value = false;
            try {
              value = response.getBoolean(fieldName);
            } catch (Exception e) {
              e.printStackTrace();
              value = false;
            }
            m.invoke(object, value);
          } else if (fieldType.endsWith("double")
              || fieldType
                  .endsWith("fieldType:class java.lang.Double")) {
            // double 類型
            Method m = object.getClass().getMethod(methodName,
                double.class);
            double value = -1D;
            try {
              value = response.getDouble(fieldName);
            } catch (Exception e) {
              e.printStackTrace();
              value = -1D;
            }
            m.invoke(object, value);
          } else if (fieldType.endsWith("char")) {
            // char類型 JSONObject 沒有char
            Method m = object.getClass().getMethod(methodName,
                String.class);
            String value = "";
            try {
              value = response.getString(fieldName);
            } catch (Exception e) {
              e.printStackTrace();
              value = "";
            }
            m.invoke(object, value);
          } else if (fieldType.endsWith("float")
              || fieldType
                  .endsWith("fieldType:class java.lang.Float")) {
            // float類型
            Method m = object.getClass().getMethod(methodName,
                double.class);
            double value = -1D;
            try {
              value = response.getDouble(fieldName);
            } catch (Exception e) {
              e.printStackTrace();
              value = -1D;
            }
            m.invoke(object, value);
          } else if (fieldType.endsWith("short")
              || fieldType
                  .endsWith("fieldType:class java.lang.Short")) {
            // short
            Method m = object.getClass().getMethod(methodName,
                short.class);
            int value = -1;
            try {
              value = response.getInt(fieldName);
            } catch (Exception e) {
              e.printStackTrace();
              value = -1;
            }
            m.invoke(object, value);
          } else if (fieldType.endsWith("byte")
              || fieldType
                  .endsWith("fieldType:class java.lang.Byte")) {
            Method m = object.getClass().getMethod(methodName,
                byte.class);
            int value = -1;
            try {
              value = response.getInt(fieldName);
            } catch (Exception e) {
              e.printStackTrace();
              value = -1;
            }
            m.invoke(object, value);
          } else if (fieldType.endsWith("long")
              || fieldType
                  .endsWith("fieldType:class java.lang.Long")) {
            Method m = object.getClass().getMethod(methodName,
                long.class);
            Long value = -1L;
            try {
              value = response.getLong(fieldName);
            } catch (Exception e) {
              e.printStackTrace();
              value = -1L;
            }
            m.invoke(object, value);
          }
        } catch (Exception e) {
          // TODO: handle exception
        }
      }
      return (T) object;
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }
}

這里需要注意一個坑,先來看一段代碼

class People {
  private String name;
  private int age;
  private String mSex;
  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 getmSex() {
    return mSex;
  }
  // 這里就出了問題
  public void setmSex(String mSex) {
    this.mSex = mSex;
  }
}

當(dāng)我們自動生成get set方法時,會將字段的首字母大寫,我們在上面拼接set 方法時,也是基于這樣的規(guī)則來拼裝的。但是 當(dāng)我們的字段名為 aAbbb 時,則生成的get set 方法則不會大寫。解決方案也很簡單,注意字段命名或者在拼接時對第二個自動進(jìn)行大小寫判斷。這樣我們自己寫的Json解析工具就搞定, 以后每次解析只需一行代碼即可OK。

今天反射就暫時講到這里。其實反射的作用遠(yuǎn)不于此,這里只是使用了反射的冰山一角,結(jié)合注解和泛型,反射可以做的事更多,但是還是和開頭講的一樣,反射用起來雖然很爽,但是不能亂射,和頻繁的射,“射”的太多?!靶浴蹦軙鰡栴}!(o(∩_∩)o )。

更多java相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Java面向?qū)ο蟪绦蛟O(shè)計入門與進(jìn)階教程》、《Java數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Java操作DOM節(jié)點技巧總結(jié)》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總

希望本文所述對大家java程序設(shè)計有所幫助。

相關(guān)文章

最新評論

永仁县| 时尚| 巧家县| 宜兰县| 承德市| 九寨沟县| 竹山县| 庆城县| 绩溪县| 加查县| 平乡县| 新民市| 拉萨市| 秀山| 天台县| 越西县| 易门县| 丹东市| 集安市| 扬州市| 开江县| 尉犁县| 高碑店市| 沙洋县| 平远县| 荥阳市| 滨海县| 涞源县| 台湾省| 拉孜县| 孟州市| 新绛县| 玛沁县| 罗平县| 公安县| 芮城县| 民乐县| 安顺市| 荆门市| 曲阳县| 长垣县|