亚洲精品中文字幕无乱码_久久亚洲精品无码AV大片_最新国产免费Av网址_国产精品3级片

java語(yǔ)言

Java反射機(jī)制應(yīng)用實(shí)踐

時(shí)間:2024-09-25 22:54:42 java語(yǔ)言 我要投稿
  • 相關(guān)推薦

Java反射機(jī)制應(yīng)用實(shí)踐

  引導(dǎo)語(yǔ):通過(guò)反射機(jī)制我們可以在運(yùn)行期間獲取對(duì)象的類型信息,利用這一特性我們可以實(shí)現(xiàn)工廠模式和代理模式等設(shè)計(jì)模式,以下是小編整理的Java反射機(jī)制應(yīng)用實(shí)踐,歡迎參考閱讀!

  反射基礎(chǔ)

  p.s: 本文需要讀者對(duì)反射機(jī)制的API有一定程度的了解,如果之前沒(méi)有接觸過(guò)的話,建議先看一下官方文檔的Quick Start。

  在應(yīng)用反射機(jī)制之前,首先我們先來(lái)看一下如何獲取一個(gè)對(duì)象對(duì)應(yīng)的反射類Class,在Java中我們有三種方法可以獲取一個(gè)對(duì)象的反射類。

  通過(guò)getClass方法

  在Java中,每一個(gè)Object都有一個(gè)getClass方法,通過(guò)getClass方法我們可以獲取到這個(gè)對(duì)象對(duì)應(yīng)的反射類:

  String s = "ziwenxie";

  Class

  通過(guò)forName方法

  我們也可以調(diào)用Class類的靜態(tài)方法forName:

  Class

  使用.class

  或者我們也可以直接使用.class:

  Class

  獲取類型信息

  在文章開(kāi)頭我們就提到反射的一大好處就是可以允許我們?cè)谶\(yùn)行期間獲取對(duì)象的類型信息,下面我們通過(guò)一個(gè)例子來(lái)具體看一下。

  首先我們?cè)趖ypeinfo.interfacea包下面新建一個(gè)接口A:

  package typeinfo.interfacea;

  public interface A { void f(); }

  接著我們?cè)趖ypeinfo.packageaccess包下面新建一個(gè)接口C,接口C繼承自接口A,并且我們還另外創(chuàng)建了幾個(gè)用于測(cè)試的方法,注意下面幾個(gè)方法的權(quán)限都是不同的。

  package typeinfo.packageaccess;

  import typeinfo.interfacea.A;

  class C implements A {

    public void f() { System.out.println("public C.f()"); }

    public void g() { System.out.println("public C.g()"); }

    protected void v () { System.out.println("protected C.v()"); }

    void u() { System.out.println("package C.u()"); }

    private void w() { System.out.println("private C.w()"); }

  }

  public class HiddenC {

    public static A makeA() { return new C(); }

  }

  在callHiddenMethod()方法中我們用到了幾個(gè)新的API,其中g(shù)etDeclaredMethod()根據(jù)方法名用于獲取Class類指代對(duì)象的某個(gè)方法,然后我們通過(guò)調(diào)用invoke()方法傳入實(shí)際的對(duì)象就可以觸發(fā)對(duì)象的相關(guān)方法:

  package typeinfo;

  import typeinfo.interfacea.A;

  import typeinfo.packageaccess.HiddenC;

  import java.lang.reflect.Method;

  public class HiddenImplementation {

    public static void main(String[] args) throws Exception {

      A a = HiddenC.makeA();

      a.f();

      System.out.println(a.getClass().getName());

      // Oops! Reflection still allows us to call g():

      callHiddenMethod(a, "g");

      // And even methods that are less accessible!

      callHiddenMethod(a, "u");

      callHiddenMethod(a, "v");

      callHiddenMethod(a, "w");

    }

    static void callHiddenMethod(Object a, String methodName) throws Exception {

      Method g = a.getClass().getDeclaredMethod(methodName);

      g.setAccessible(true);

      g.invoke(a);

    }

  }

  從輸出結(jié)果我們可以看出來(lái),不管是public,default,protect還是pricate方法,通過(guò)反射類我們都可以自由調(diào)用。當(dāng)然這里我們只是為了顯示反射的強(qiáng)大威力,在實(shí)際開(kāi)發(fā)中這種技巧還是不提倡。

  public C.f()

  typeinfo.packageaccess.C

  public C.g()

  package C.u()

  protected C.v()

  private C.w()

  應(yīng)用實(shí)踐

  我們有下面這樣一個(gè)業(yè)務(wù)場(chǎng)景,我們有一個(gè)泛型集合類List<Class>,我們需要統(tǒng)計(jì)出這個(gè)集合類中每種具體的Pet有多少個(gè)。由于Java的泛型擦除,注意類似List的做法肯定是不行的,因?yàn)榫幾g器做了靜態(tài)類型檢查之后,到了運(yùn)行期間JVM會(huì)將集合中的對(duì)象都視為Pet,但是并不會(huì)知道Pet代表的究竟是Cat還是Dog,所以到了運(yùn)行期間對(duì)象的類型信息其實(shí)全部丟失了。p.s: 關(guān)于泛型擦除:我在上一篇文章里面有詳細(xì)解釋,感興趣的朋友可以看一看。

  為了實(shí)現(xiàn)我們上面的例子,我們先來(lái)定義幾個(gè)類:

  public class Pet extends Individual {

    public Pet(String name) { super(name); }

    public Pet() { super(); }

  }

  public class Cat extends Pet {

    public Cat(String name) { super(name); }

    public Cat() { super(); }

  }

  public class Dog extends Pet {

    public Dog(String name) { super(name); }

    public Dog() { super(); }

  }

  public class EgyptianMau extends Cat {

    public EgyptianMau(String name) { super(name); }

    public EgyptianMau() { super(); }

  }

  public class Mutt extends Dog {

    public Mutt(String name) { super(name); }

    public Mutt() { super(); }

  }

  上面的Pet類繼承自Individual,Individual類的的實(shí)現(xiàn)稍微復(fù)雜一點(diǎn),我們實(shí)現(xiàn)了Comparable接口,重新自定義了類的比較規(guī)則,如果不是很明白的話,也沒(méi)有關(guān)系,我們已經(jīng)將它抽象出來(lái)了,所以不理解實(shí)現(xiàn)原理也沒(méi)有關(guān)系。

  public class Individual implements Comparable{

    private static long counter = 0;

    private final long id = counter++;

    private String name; // name is optional

    public Individual(String name) { this.name = name; }

    public Individual() {}

    public String toString() {

      return getClass().getSimpleName() + (name == null ? "" : " " + name);

    }

    public long id() { return id; }

    public boolean equals(Object o) {

      return o instanceof Individual && id == ((Individual)o).id;

    }

    public int hashCode() {

      int result = 17;

      if (name != null) {

        result = 37 * result + name.hashCode();

      }

      result = 37 * result + (int) id;

      return result;

    }

    public int compareTo(Individual arg) {

      // Compare by class name first:

      String first = getClass().getSimpleName();

      String argFirst = arg.getClass().getSimpleName();

      int firstCompare = first.compareTo(argFirst);

      if (firstCompare != 0) {

        return firstCompare;

      }

      if (name != null && arg.name != null) {

        int secendCompare = name.compareTo(arg.name);

        if (secendCompare != 0) {

          return secendCompare;

        }

      }

      return (arg.id < id ? -1 : (arg.id == id ? 0 : 1));

    }

  }

  下面創(chuàng)建了一個(gè)抽象類PetCreator,以后我們通過(guò)調(diào)用arrayList()方法便可以直接獲取相關(guān)Pet類的集合。這里使用到了我們上面沒(méi)有提及的newInstance()方法,它會(huì)返回Class類所真正指代的類的實(shí)例,這是什么意思呢?比如說(shuō)聲明new Dog().getClass().newInstance()和直接new Dog()是等價(jià)的。

  public abstract class PetCreator {

    private Random rand = new Random(47);

    // The List of the different getTypes of Pet to create:

    public abstract List<Class> getTypes();> allTypes = Collections.unmodifiableList(> types = allTypes.subList(> getTypes() {, Integer> { baseType; baseType) { type = obj.getClass(); type) { superClass = type.getSuperclass();, Integer> pair : entrySet()) {

        result.append(pair.getKey().getSimpleName());

        result.append("=");

        result.append(pair.getValue());

        result.append(", ");

      }

      result.(result.length() - 2, result.length());

      result.append("} ");

      return result.toString();

    }

  }

【Java反射機(jī)制應(yīng)用實(shí)踐】相關(guān)文章:

Java反射機(jī)制學(xué)習(xí)總結(jié)10-02

Java實(shí)現(xiàn)反射學(xué)習(xí)函數(shù)的應(yīng)用10-22

關(guān)于Java 反射的簡(jiǎn)介08-27

java的緩存機(jī)制07-29

java使用反射技術(shù)示例06-18

深入理解java的反射07-16

java ClassLoader機(jī)制講解07-31

java的緩存機(jī)制簡(jiǎn)介09-06

java垃圾回收機(jī)制06-28

java的應(yīng)用范圍06-24