2016-10-03 136 views
0

我想創建一個用作函數參數的泛型類型的實例。假設下面的類有一點不同的表示Java:創建作爲函數參數傳遞的泛型類型的實例

class Point1 { 
     double x, y; 
     public Point1 (double x_, double y_) {x=x_; y = y_;} 
} 

class Point2 { 
     double lat, lon; 
     public Point2 (double lat_, double lon_) {lat = lat_; lon = lon_;} 
} 

有一類建立基於反射

public class GType<T> { 
    private Class<T> UType; 
    public GType(Class<T> gt) {UType = gt;} 

    public T get(double p1, double p2){ 
      try    { 
        Class[] constrArg = new Class[2]; 
        constrArg[0] = double.class; 
        constrArg[1] = double.class; 
        return UType.getDeclaredConstructor(constrArg).newInstance(p1, p2); 
      } 

      catch (Exception e) { 
        e.printStackTrace(); 
        return null; 
      } 
    } 
} 

雖然

public static void main(String[] args) { 
    GType<Point1> gt = new GType<>(Point1.class); 
    Point1 p = gt.get(10,10); 
} 

作品以及通用類型的實例,以下構造

public static <Point> void test (Point point){ 
      GType<Point> g = new GType<>(Point.class); //Error 
      point = g.get(10,10,10); 
    } 

    public static void main(String[] args) { 
     Point1 p1; 
     test (p1); 
    } 

導致

Error: Cannot select from a type variable 

如何創建測試()函數中的點1類型,其中點=點1的實例?謝謝你的幫助。

更新問題:

是否存在與LAMBDA功能的解決方案與未知點實例的方法:

public static <Point> void test (List<Point> points) 
    { 
      GType<Point> g = new GType<>((Class)points.getClass()); 
      Point point = g.get(10,10); 
      points.add(point); 
    } 
+1

你知道什麼是通用方法嗎?你認爲方法聲明中的''是什麼? –

+0

@ Sotirios:我的母語是C++,我經常使用模板:-)我希望Point = Point1,但它在Java中可能不正確...... – justik

+1

您不需要反射來實例化泛型類。只是比較喜歡工廠(比如'Supplier '的一個實例,它會返回一個新的'T'實例)。 –

回答

1

Java泛型是隻是靜態類型檢查。你不能實例化一個類型參數,並且你不能獲得類型參數的.class

既然你傳遞一個Point情況下,你可以問的實例作爲類:

point.getClass(); 

這樣可以傳遞給GType構造。

但是,這只是您的直接問題的答案。 Lyubomyr在他的評論中是正確的,他表示一個更好的Java成語是通過一個工廠lambda函數傳遞的。在你的情況,你想一個lambda形狀像下面這樣:

(double, double) -> Point 

由於這種形狀沒有在標準庫提供的,你應該創建自己:

@FunctionalInterface 
public interface PointConstructor<Point> { 
    Point create(double x, double y); 
} 

你的GType會成爲

public class GType<T> { 
    private PointConstructor<T> cxor; 
    public GType(PointConstructor<T> cxor) { this.cxor = cxor; } 

    public T get(double p1, double p2) { 
    return cxor.create(p1, p2); 
    } 
} 

,你把它作爲

GType<Point2> gt = new GType<>(Point2::new); 

這兩個工作在運行時,並滿足靜態類型安全。

+0

@ Marko:給反思的解決方案。你認爲GenericType g = new GenericType <>((Class)point.getClass())? – justik

+0

是的,您可以看到如何禁用靜態類型檢查,因爲由於虛擬函數調用而不可能發生,從而導致靜態類型系統無法實現的動態分派。 –

+0

@ Marko:GType pg = new GType(Point2 :: new)導致錯誤:方法參考中的參數類型不兼容 – justik

相關問題