使用泛型时我的工厂模式有问题。我有这个界面,一切都是通用的:
public interface Connection<T> {
/* methods */
}
显然,我有这个实现:
public class ImplConnection<V> implements Connection<V> {
/* body */
}
然后我有这个工厂,必须创建一个连接实例:
public class ConnectionFactory<V, C extends Connection<V>> {
private final Class<V> contentType;
private final Class<C> connectionType;
public ConnectionFactory(Class<V> contentType, Class<C> connectionType) {
this.contentType = contentType;
this.connectionType = connectionType;
}
public C newConnection() {
try {
return connectionType.newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
我试图在运行时使用此实例化连接(我使用Integer
作为泛型类型的参数):
connectionFactory = new ConnectionFactory<Integer, Connection<Integer>>(Integer.class, Connection.class);
但它说:
The constructor ConnectionFactory <Integer,Connection<Integer>>(Class<Integer>, Class<Connection>) is undefined.
答案 0 :(得分:4)
传递类参数时,Connection
不会扩展Connection<Integer>
。因此Class<Connection>
不能作为Class<? extends Connection<Integer>>
的参数给出。这就是您的错误背后隐藏的内容。
如果你想保留这种模式,你应该怎么做才有这样的事情:
public class IntegerConnection implements Connection<Integer> {}
这样可行。
但是,一般来说,您知道可以创建一个通用实例而无需输入任何特殊内容吗?
public class ConnectionFactory {
public <T> Connection<T> newConnection() {
return new ConnectionImpl<T>();
}
}
你可以像这样使用它:
Connection<Integer> connection = connectionFactory.newInstance();
答案 1 :(得分:1)
当我使用泛型时,我经常使用Guava TypeToken
。他们非常有帮助。你的课可能是这样的:
public class ConnectionFactory<V, C extends Connection<V>> {
private final TypeToken<V> contentType;
private final TypeToken<C> connectionType;
public ConnectionFactory() {
this.contentType = new TypeToken<V>(getClass()) {};
this.connectionType = new TypeToken<C>(getClass()) {};
}
public C newConnection() {
try {
return (C) connectionType.getRawType().newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
试一试。