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);
这既能在运行时工作,又能满足静态类型安全。
我想创建一个用作函数参数的泛型实例。假设以下 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);
这既能在运行时工作,又能满足静态类型安全。