JAva汎用メソッドタイプ導出


http://blog.csdn.net/zerro99/article/details/6118218
  • コンパイラが汎用方法の実際のタイプパラメータを判断する過程をタイプ推定と呼び、タイプ推定の実現方法は非常に複雑な過程である.
  • は、汎用メソッドが呼び出されたときに実際に伝達するパラメータタイプまたは戻り値タイプから推定する.具体的なルールは、
  • である.
  • あるタイプの変数がメソッドパラメータのリストまたは戻り値の1つでのみ呼び出された場合、そのメソッドを呼び出すときのその場所の実際のタイプに基づいて決定される.すなわち、メソッドを呼び出すときに渡される実際のタイプまたはメソッドの戻り値のタイプに直接基づいて汎用メソッドのパラメータタイプを決定する.例えば、swap(new String[3,3,4]--->static  void swap(E[] a,int i,int t)
  • あるタイプの変数がメソッドのパラメータリストと戻り値で複数回利用され、メソッドが呼び出されたときの実際のタイプが同じである場合、この汎用メソッドのパラメータタイプも明らかに知ることができる.例えば、add(3,5)-->staticT add(Ta,Tb)
  • あるタイプの変数がメソッドのパラメータリストと戻り値の中で何度も利用され、またメソッドを呼び出す時にこれらの多くの実際のタイプはまた異なるタイプに対応し、戻り値がvoidである場合、この時に多くの実際の変数タイプの最大交差を取る.例えば、fill(new Integer[3]、3.5 f)-->staticvoid fill(T[]a,T i)であり、この時TはNumberであり、コンパイルはエラーを報告せず、しかし、運転に問題があります.
  • あるタイプ変数がメソッドのパラメータリストと戻り値で複数回利用され、戻り値が空ではなく、メソッドを呼び出すときにこれらの複数の実際のタイプが異なるタイプに対応する場合、戻り値のタイプ.int x=add(3,3.5 f)-->staticT add(Ta,Tb)
  • を優先的に考慮する.
  • パラメータタイプのタイプ推定は伝達性を有し,copy(new Integer[5],new String[5])-->staticvoid copy(T[]a,T[]b)  TはObjectタイプで問題ないcopy(new Vector(),new Integer[5])-->staticvoid copy(Collectiona,T[]b)    new Vector()ではTをStringタイプと決定するが、new Integer[5]はStringタイプではなく、
  • とエラーが報告される
    package all;
    
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.List;
    
    /**
     * java          
     * @author root
     *
     */
    public class TypeInfer {
        /**
         * 1.                       ,
         *                              
         * @param <T>
         * @param value
         */
        public static<T> void onlyOneCall(T value){
    	System.out.println(value);
        }
        /**
         *               ,             
         * @param <T>
         * @param a
         * @param b
         * @return
         */
        public static<T> T sameParam(T a,T b){
    	return a;
        }
        /**
         *      ,            ,              ,        
         *  : noSamePram(new Integer[2],new Float(2.0))//           Number,      
         * @param <T>
         * @param array
         * @param b
         */
        public static<T> void noSameParam(T[]array,T b){
    	int len = array.length;
    	for(int i=0;i<len;i++)
    	    array[i] = b;
        }
        /**
         *      ,       ,      ,           
         * @param <T>
         * @param a
         * @param b
         * @return
         */
        public static<T> T noSameParamWithReturn(T a,T b){
    	return b;
        }
        /**
         *          ,             ,  list<T>  T              , 
         * copy(new List<String> list,new Integer(1)),T   string,   array integer,    ,    
         *   ,     ,  ,             ,           
         *  : copy(Collection<T> col,T[]array),copy(new List<String>,new Integer[])       T      string,      Integer,     
         * @param <T>
         * @param col
         * @param array
         */
        public static<T> void copy(Collection<T>col,T[]array){
    	
        }
        public static<T> T copycopy(T[]array,Collection<T>col){
    	return array[0];
        }
        public static<T> T copy(T a,T b){
    	return a;
        }
        public static void main(String args[]){
    	Integer a  = new Integer(1);
    	Long b = new Long(2);
    	//noSameParam(new Integer[3],new Float(1));
    	List<String> list = new ArrayList<String>();
    	Integer [] array = new Integer[]{1,2,3};
    	copy(list,array);
    	copy(array,list);
    	copy(new String(),new Integer(2));
        }
    }
    

    参照先:http://lsq6063.iteye.com/blog/693751
    http://www.ibm.com/developerworks/cn/java/j-jtp04298.html
    package all;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    /**
     * 一般的なまとめについて
     * @author root
     *
     */
    public class Summary {
       /*
         * 1.なぜListは、値を挿入せずにTタイプの値を返すことができるのか
         *
    リストのうち<>のタイプはリストに要素が存在するタイプであり、もちろん
         * リストlistを定義するなど、そのサブクラスを含めます.
         * このリストは、List,List,Listである可能性があります.
         * 私たちが追加した値はInteger,Long,Float,Doubleかもしれません
         * リストにDoubleを追加すると
         * エラーが発生したのは、listのタイプパラメータがどのタイプなのか分からないためです.
         * リストのパラメータと E(タイプパラメータ)に関する方法、例えば、list.set()、list.put()など
         * 2.リストは、リストがリストである場合にかかわらず、Tタイプの値を返すことができる理由
         * List,Listは、挿入された要素が必ずNumberのサブクラスであるため、
         * Numberタイプの要素を返すことができます
         */
        public static void get(List list) {
    List intlist = new ArrayList();
        }
       /**
         * どうしてListはlistの中のTタイプの値を挿入することができて、getの出た値はObjectだけです
         *   List例えば、Listは、伝達されるパラメータが
         *   List,List,Listは、これらのセット全体にデータを追加します.
         *   いずれもIntegerの親なので、前のいずれであってもリストにIntegerデータを挿入できます.
         *   データを取り出すのも同じで、listに挿入されたデータに対して、私たちはそれがどれなのか分かりません.私たちはただそれらがすべて
         *   Integerの親は、最大Objectであるため、取り出したデータ型はObjectである
         *   
         */
        public static void set(List list) {
        }
       /**
         * このメソッドの戻り値は任意のタイプで、パラメータは必ずComparableインタフェースを実装します.
         * @param
         * @param list
         * @return
         */
        public static T binarySearch(List> list){
    //list.get(0).compareTo(T o)/このlist戻りタイプはComparable
    return null;
        }
        public static> T max(Listlist) {
    //list.get(0).compareTo(T o) 
    return null;
        }
       //listに要素を挿入する方法、2つの方法
        public static void addAllType(List list,Object e) {
    final List thatlist = list;
    thatlist.add(e);
        }
        public static void main(String args[]) {
    List intList = new ArrayList();
    Collections.addAll(intList,1,2,3,4);
    List numList = intList;
    Object resulst = numList.get(0);
        }
        public static void setTest() {
    List numlist = new ArrayList();
    List> comList = new ArrayList>();
    set(comList);
        }
        public static void testAllType() {
    List list = new ArrayList();
    List lists = list;
        }
    }