泛型是否允许Java编译器检查映射中键和值的类型?
我希望有一个映射,其中键是一个接口类,对应的值是实现该接口的类。换句话说,键和值类型是相关的 我当前的方法实现添加到映射,并获取实现类的实例,如下所示:泛型是否允许Java编译器检查映射中键和值的类型?,java,generics,Java,Generics,我希望有一个映射,其中键是一个接口类,对应的值是实现该接口的类。换句话说,键和值类型是相关的 我当前的方法实现添加到映射,并获取实现类的实例,如下所示: // should be something like Class<T>, Class<? extends T> static Map<Class<?>, Class<?>> map = new HashMap<Class<?>, Class<?>>
// should be something like Class<T>, Class<? extends T>
static Map<Class<?>, Class<?>> map = new HashMap<Class<?>, Class<?>> ();
public static <T> void add(Class<T> interfaceT,
Class<? extends T> implementationT) {
map.put(interfaceT, implementationT);
}
public static <T> T get(Class<T> interfaceT) {
// cast caused by definition not complete.
Class<T> implementationT = (Class<T>) map.get(interfaceT);
// try catch stuff omitted
T t = implementationT.newInstance();
return t;
}
//应该类似于Class,Class,Class>map=newhashmap>();
公共静态无效添加(类接口集,
类看起来目标类似于Josh Bloch在他的案例中描述的“类型安全异构容器”,他正在将一个类型(Class
)映射到一个(已经实例化的)实例(T
)
您可以执行类似的操作,使用而不是cast
:
final class Factory
{
private Map<Class<?>, Class<?>> map = new HashMap<Class<?>, Class<?>>();
<T> void map(Class<T> type, Class<? extends T> impl)
{
map.put(type, impl.asSubclass(type));
}
private <T> Class<? extends T> get(Class<T> type)
{
Class<?> impl = map.get(type);
if (impl == null)
throw new IllegalArgumentException("Unknown type: " + type);
return impl.asSubclass(type);
}
<T> T create(Class<T> type)
throws Exception
{
Class<? extends T> impl = get(type);
Constructor<? extends T> ctor = impl.getConstructor();
return ctor.newInstance();
}
}
最终类工厂
{
私有映射>映射=新HashMap>();
虚空图(类类型,类我建议a。下面是
公共接口自行车{
公共字符串getWheels();
公共int getSize();
}
公共级山地自行车{
@凌驾
公共int getSize(){
返回24;
}
@凌驾
公共字符串getWheels(){
返回“踩踏”;
}
@凌驾
公共字符串toString(){
字符串newLine=System.getProperty(“line.separator”);
StringBuilder sb=新的StringBuilder();
sb.append(“类型:MOUNTAIN”).append(换行符);
sb.append(“Wheels:”).append(getWheels()).append(换行符);
sb.append(“大小:”).append(getSize()).append(换行符);
使某人返回字符串();
}
}
公共级巡洋舰自行车{
@凌驾
公共int getSize(){
返回26;
}
@凌驾
公共字符串getWheels(){
返回“平滑”;
}
@凌驾
公共字符串toString(){
字符串newLine=System.getProperty(“line.separator”);
StringBuilder sb=新的StringBuilder();
sb.追加(“类型:巡洋舰”)。追加(换行符);
sb.append(“Wheels:”).append(getWheels()).append(换行符);
sb.append(“大小:”).append(getSize()).append(换行符);
使某人返回字符串();
}
}
公共类BikeProxy实现调用处理程序{
私有对象对象;
公共静态对象newInstance(对象obj)
{
返回java.lang.reflect.Proxy.newProxyInstance(obj.getClass())
.getClassLoader(),obj.getClass().getInterfaces(),
新的BikeProxy(obj));
}
公共静态T newInstance(字符串类名称)
{
尝试
{
返回(T)newInstance(Class.forName(className));
}
catch(classnotfounde异常)
{
抛出新的运行时异常(e);
}
}
公共静态T newInstance(类bikeClass)
{
尝试
{
返回(T)java.lang.reflect.Proxy.newProxyInstance(Bike.class.getClassLoader(),新类[]{Bike.class},
新的BikeProxy(bikeClass.newInstance());
}
捕获(例外e)
{
抛出新的运行时异常(e);
}
}
私人BikeProxy(对象obj)
{
this.obj=obj;
}
公共对象调用(对象代理,方法m,对象[]args)
扔掉的
{
客观结果;
尝试
{
结果=m.invoke(obj,args);
}
捕获(调用TargetException e)
{
抛出e.getTargetException();
}
捕获(例外e)
{
抛出新的运行时异常(e);
}
返回结果;
}
}
公共类代理测试器
{
公共静态void main(字符串[]args)
{
Bike mountainBike=BikeProxy.newInstance(mountainBike.class);
System.out.println(山地车);
Bike mountainBike2=BikeProxy.newInstance(MountainBike.class.getName());
系统输出打印LN(mountainBike2);
Bike cruiserBike=BikeProxy.newInstance(cruiserBike.class);
System.out.println(巡洋舰型);
Bike cruiserBike2=BikeProxy.newInstance(CruiserBike.class.getName());
系统输出打印LN(cruiserBike2);
}
}
谢谢。您的解决方案就在眼前。我现在将重读generics.pdf-这是一个相当陡峭的学习曲线:)
final class Factory
{
private Map<Class<?>, Class<?>> map = new HashMap<Class<?>, Class<?>>();
<T> void map(Class<T> type, Class<? extends T> impl)
{
map.put(type, impl.asSubclass(type));
}
private <T> Class<? extends T> get(Class<T> type)
{
Class<?> impl = map.get(type);
if (impl == null)
throw new IllegalArgumentException("Unknown type: " + type);
return impl.asSubclass(type);
}
<T> T create(Class<T> type)
throws Exception
{
Class<? extends T> impl = get(type);
Constructor<? extends T> ctor = impl.getConstructor();
return ctor.newInstance();
}
}
public interface Bike {
public String getWheels();
public int getSize();
}
public class MountainBike implements Bike {
@Override
public int getSize() {
return 24;
}
@Override
public String getWheels() {
return "Treaded";
}
@Override
public String toString() {
String newLine = System.getProperty("line.separator");
StringBuilder sb = new StringBuilder();
sb.append("Type: MOUNTAIN").append(newLine);
sb.append("Wheels: ").append(getWheels()).append(newLine);
sb.append("Size: ").append(getSize()).append(newLine);
return sb.toString();
}
}
public class CruiserBike implements Bike {
@Override
public int getSize() {
return 26;
}
@Override
public String getWheels() {
return "Smooth";
}
@Override
public String toString() {
String newLine = System.getProperty("line.separator");
StringBuilder sb = new StringBuilder();
sb.append("Type: CRUISER").append(newLine);
sb.append("Wheels: ").append(getWheels()).append(newLine);
sb.append("Size: ").append(getSize()).append(newLine);
return sb.toString();
}
}
public class BikeProxy implements InvocationHandler {
private Object obj;
public static Object newInstance(Object obj)
{
return java.lang.reflect.Proxy.newProxyInstance(obj.getClass()
.getClassLoader(), obj.getClass().getInterfaces(),
new BikeProxy(obj));
}
public static <T> T newInstance(String className)
{
try
{
return (T) newInstance(Class.forName(className));
}
catch (ClassNotFoundException e)
{
throw new RuntimeException(e);
}
}
public static <T> T newInstance(Class<T> bikeClass)
{
try
{
return (T) java.lang.reflect.Proxy.newProxyInstance(Bike.class.getClassLoader(), new Class[]{Bike.class},
new BikeProxy(bikeClass.newInstance()));
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
private BikeProxy(Object obj)
{
this.obj = obj;
}
public Object invoke(Object proxy, Method m, Object[] args)
throws Throwable
{
Object result;
try
{
result = m.invoke(obj, args);
}
catch (InvocationTargetException e)
{
throw e.getTargetException();
}
catch (Exception e)
{
throw new RuntimeException(e);
}
return result;
}
}
public class ProxyTester
{
public static void main(String[] args)
{
Bike mountainBike = BikeProxy.newInstance(MountainBike.class);
System.out.println(mountainBike);
Bike mountainBike2 = BikeProxy.newInstance(MountainBike.class.getName());
System.out.println(mountainBike2);
Bike cruiserBike = BikeProxy.newInstance(CruiserBike.class);
System.out.println(cruiserBike);
Bike cruiserBike2 = BikeProxy.newInstance(CruiserBike.class.getName());
System.out.println(cruiserBike2);
}
}