我想创建一个用作函数参数的泛型类型的实例。假设以下类具有不同的点表示
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);
}
答案 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);
这两者都在运行时工作,并且满足静态类型安全性。