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

Java: Create instance of a generic type passed as a function parameter

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

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_;}
}

有class根据反射创建泛型实例

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

Java 泛型只是静态类型检查。您无法实例化类型参数,也无法获取类型参数的 .class

因为你传入了一个 Point 实例,你可以向实例询问它的 class:

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

这既能在运行时工作,又能满足静态类型安全。