问题描述
我正在尝试通过以下代码在Java 15中使用通用类
@Singleton
public class GenericRepository<T> implements IGenericRepository<T>{
private final MongoClient mongoClient;
public GenericRepository(MongoClient mongoClient) {
this.mongoClient = mongoClient;
}
public MongoCollection<T> getCollection(String collectionName) {
return mongoClient
.getDatabase("main")
.getCollection(collectionName,T.class);
}
}
我不能使用T.class,如何解决这个问题
我找到的解决方案
@Singleton
public class GenericRepository<T> implements IGenericRepository<T>{
private final MongoClient mongoClient;
private final Class<T> typeParameterClass;
public GenericRepository(MongoClient mongoClient,Class<T> typeParameterClass) {
this.mongoClient = mongoClient;
this.typeParameterClass = typeParameterClass;
}
public MongoCollection<T> getCollection(String collectionName) {
return mongoClient
.getDatabase("main")
.getCollection(collectionName,this.typeParameterClass);
}
}
解决方法
单例类,其唯一的构造函数带有参数和进行了参数化?
您的代码没有意义。在其他情况下,您遇到的问题很重要,但与此无关。没有直接解决此问题的方法(问题是:泛型被删除),但是有不同的代码样式可以避免这种情况。
问题在于,因为该问题甚至都不适用于这种情况,所以很难解释人们将如何重写此代码,从而使该问题作为一般原理消失。
在这里,您只是...删除类型参数,摆脱该接口(通常,如果您有IFoo
徘徊,那是不对的),就这么简单。
如果您想对此概念进行概括,以便可以做很多(假设您有一个此类可以检索Foos,而另一个可以检索Bars),则可以获取{{1} },特别是在<X>
中,尽管有点棘手(您可以从自己的public class FooFetcher implements GenericFetcher<X>
中使用getGenericSuper
,然后从那里获取。在这种情况下,有很多警告,所以我赢了对此不做进一步扩展,只知道您可以做到这一点。
如果在另一种情况下确实需要以可在运行时查询的方式传达泛型,则样式的问题是java.lang.Class
和a class object
重叠但不相同。 a generics param
有一个类对象(int
),但是int.class
不是有效的Java代码。 List<int>
是有效的泛型(List<String>
是有效的Java),但是List<List<String>> x;
不是事物,永远不会,只有List<String>.class
是。 List.class
,?
也是如此,这是有效的泛型,但显然根本无法用? extends Map<?,List<? extends Number>> & Serializable
类型表示。因此,如果您确实希望将泛型作为运行时可查询的概念,请在网络上搜索“超级类型令牌”,但请注意,它们所需的代码比此处的更多,而不是更少。它们实际上实际上能够准确地代表泛型。
作为一般经验法则,如果您依靠java.lang.Class的泛型将代码粘合在一起,那么您做错了什么,并且您可能想要工厂。