Java:创建作为函数参数传递的泛型类型的实例

时间:2016-10-03 17:49:09

标签: java generics types instance

我想创建一个用作函数参数的泛型类型的实例。假设以下类具有不同的点表示

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

如何在test()函数中创建Point1类型的实例,其中Point = Point1?谢谢你的帮助。

更新了问题:

对于具有未知Point实例的方法,是否存在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 :(得分:1)

Java Generics只是关于静态类型检查。您无法实例化类型参数,也无法获得类型参数的.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);

这两者都在运行时工作,并且满足静态类型安全性。