<address id="ousso"></address>
<form id="ousso"><track id="ousso"><big id="ousso"></big></track></form>
  1. Java反射機制應用實踐

    時間:2025-09-12 11:39:55 java語言

    Java反射機制應用實踐

      引導語:通過反射機制我們可以在運行期間獲取對象的類型信息,利用這一特性我們可以實現工廠模式和代理模式等設計模式,以下是小編整理的Java反射機制應用實踐,歡迎參考閱讀!

      反射基礎

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

      在應用反射機制之前,首先我們先來看一下如何獲取一個對象對應的反射類Class,在Java中我們有三種方法可以獲取一個對象的反射類。

      通過getClass方法

      在Java中,每一個Object都有一個getClass方法,通過getClass方法我們可以獲取到這個對象對應的反射類:

      String s = "ziwenxie";

      Class

      通過forName方法

      我們也可以調用Class類的靜態方法forName:

      Class

      使用.class

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

      Class

      獲取類型信息

      在文章開頭我們就提到反射的一大好處就是可以允許我們在運行期間獲取對象的類型信息,下面我們通過一個例子來具體看一下。

      首先我們在typeinfo.interfacea包下面新建一個接口A:

      package typeinfo.interfacea;

      public interface A { void f(); }

      接著我們在typeinfo.packageaccess包下面新建一個接口C,接口C繼承自接口A,并且我們還另外創建了幾個用于測試的方法,注意下面幾個方法的權限都是不同的。

      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()方法中我們用到了幾個新的API,其中getDeclaredMethod()根據方法名用于獲取Class類指代對象的某個方法,然后我們通過調用invoke()方法傳入實際的對象就可以觸發對象的相關方法:

      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());

          /pic/p>

          callHiddenMethod(a, "g");

          /pic/p>

          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);

        }

      }

      從輸出結果我們可以看出來,不管是public,default,protect還是pricate方法,通過反射類我們都可以自由調用。當然這里我們只是為了顯示反射的強大威力,在實際開發中這種技巧還是不提倡。

      public C.f()

      typeinfo.packageaccess.C

      public C.g()

      package C.u()

      protected C.v()

      private C.w()

      應用實踐

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

      為了實現我們上面的例子,我們先來定義幾個類:

      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類的的實現稍微復雜一點,我們實現了Comparable接口,重新自定義了類的比較規則,如果不是很明白的話,也沒有關系,我們已經將它抽象出來了,所以不理解實現原理也沒有關系。

      public class Individual implements Comparable{

        private static long counter = 0;

        private final long id = counter++;

        private String name; /pic/p>

        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) {

          /pic/p>

          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));

        }

      }

      下面創建了一個抽象類PetCreator,以后我們通過調用arrayList()方法便可以直接獲取相關Pet類的集合。這里使用到了我們上面沒有提及的newInstance()方法,它會返回Class類所真正指代的類的實例,這是什么意思呢?比如說聲明new Dog().getClass().newInstance()和直接new Dog()是等價的。

      public abstract class PetCreator {

        private Random rand = new Random(47);

        /pic/p>

        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反射機制應用實踐】相關文章:

    Java反射機制02-10

    java中反射機制07-19

    Java反射機制學習總結12-08

    Java實現反射學習函數的應用08-11

    關于Java 反射的簡介10-29

    java使用反射技術示例10-08

    java的緩存機制03-06

    深入理解java的反射11-28

    java的緩存機制簡介12-17

    <address id="ousso"></address>
    <form id="ousso"><track id="ousso"><big id="ousso"></big></track></form>
    1. 日日做夜狠狠爱欧美黑人