Java反射操作汎用インタフェース


抽象クラスやインタフェースにおける汎用情報を反射的に取得する操作も一般的である.実際の開発では,バックグラウンドデータのJsonデータを解析し,対応する汎用実体クラスを生成し,汎用情報を反射して取得する操作を用いる.
実戦事例
大まかな考え方:
  • getGenericInterfaces()は、汎用インタフェースのType配列を取得する.
  • getActualTypeArguments()は、汎用インタフェースの実際のタイプを取得する.

  • 1.汎用インタフェースを定義します.
    package com.xingen.classdemo.genericity;
    
    /**
     * Created by ${  } on 2018/2/16 0016.
     *   :http://blog.csdn.net/hexingen
     *
     *   :https://www.cnblogs.com/whitewolf/p/4355541.html
     */
    public interface GenericityInterface {
    
        T doThing(K k);
    
    }

    2.特定のタイプを取得する実装クラスを定義します.
    package com.xingen.classdemo.genericity;
    
    import java.lang.reflect.ParameterizedType;
    import java.lang.reflect.Type;
    
    /**
     * Created by ${  } on 2018/2/16 0016.
     *   :http://blog.csdn.net/hexingen
     * 

    * */

    public class GenericityInterfaceImp implements GenericityInterface { // private Class> kClass,tClass; public GenericityInterfaceImp() { getGenericityMessage(GenericityInterfaceImp.class); } @Override public Bean doThing(String s) { return new Bean(s); } public void getGenericityMessage(Class> mClass) { try { // Type[] intefaceTypeArray = mClass.getGenericInterfaces(); if (intefaceTypeArray == null && intefaceTypeArray.length == 0) { return; } // Type type = intefaceTypeArray[0]; if (!(type instanceof ParameterizedType)) { // Object return; } // Type[] parameterizedType = ((ParameterizedType) type).getActualTypeArguments(); kClass=TypeUtils.getClass(parameterizedType[0]); tClass=TypeUtils.getClass(parameterizedType[1]); }catch (Exception e){ e.printStackTrace(); } } public Class> getkClass() { return kClass; } public Class> gettClass() { return tClass; } public static GenericityInterfaceImp newInstance(){ return new GenericityInterfaceImp(); } }

    3.ツールクラスを定義します.TypeとClass間の変換に使用します.
    package com.xingen.classdemo.genericity;
    
    import java.lang.reflect.Type;
    
    /**
     * Created by ${  } on 2018/2/16 0016.
     *   :http://blog.csdn.net/hexingen
     *
     *   Type    class
     */
    public class TypeUtils {
        private static final String TYPE_NAME_PREFIX = "class ";
    
        public static String getClassName(Type type) {
            if (type==null) {
                return "";
            }
            String className = type.toString();
            if (className.startsWith(TYPE_NAME_PREFIX)) {
                className = className.substring(TYPE_NAME_PREFIX.length());
            }
            return className;
        }
    
        public static Class> getClass(Type type)
                throws ClassNotFoundException {
            String className = getClassName(type);
            if (className==null || className.isEmpty()) {
                return null;
            }
            return Class.forName(className);
        }
    }

    4.エンティティ・クラスの定義:汎用型の実際のタイプを指定する
    public class Bean {
        private String work;
    
        public Bean() {
        }
    
        public Bean(String work) {
            this.work = work;
        }
    
        public String getWork() {
            return work;
        }
    
        public void setWork(String work) {
            this.work = work;
        }
    }

    5.プログラムエントリmain()、実行:
    public class Client {
    
        public static void main(String[] args) {
            useGenericity();
        }
    
        /**
         *       
         */
        public static  void useGenericity(){
            GenericityInterfaceImp imp=GenericityInterfaceImp.newInstance();
            System.out.println("         : K  "+imp.getkClass().getName()+" T  :"+imp.gettClass().getName());
        }
    }

    6.運転結果は以下の通り:
             : K  java.lang.String T  :com.xingen.classdemo.genericity.Bean
    

    このケースのプロジェクトコード:https://github.com/13767004362/JavaDemo/tree/master/ClassDemo