有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java泛型

谁来帮我弄这些仿制药

如果您有一个重载方法,其类型不同,可以作为参数,那么可以编写一个泛型方法,在运行时调用正确的方法吗?(抱歉,如果我的java技术很差,如果是)

例如:

public interface CoolInterface {
   setOverloadedValue(String o);
   setOverloadedValue(Integer o);
   setOverloadedValue(Date o);
}

public interface ClazzProvider {
   Class getClazz();
}

public class SomeUncoolClass {

   @AutowiredMagic CoolInterface coolGuy;
   @AutowiredMagic ClazzProvider clazzyProvider;

   public void helpMeMethod() {
      coolGuy.setOverloadedValue(getValue(clazzyProvider.getClazz()));
   }

   private ??? getValue(???) {
      return ???;
   }
}

getValue()的方法签名是什么?我如何实现它


共 (4) 个答案

  1. # 1 楼答案

    否-重载是在编译时选择的,编译器无法判断要使用哪个重载

    您可能想看看Visitor Pattern作为一种解决方法,以解决您想要接受的类型在您的控制之下的情况,但是当您想要接受String/Date/Object时,它没有多大帮助:(

  2. # 2 楼答案

    您可以实现类似于Joshua Bloch在有效的Java第二版中所称的类型安全异构容器(THC)的功能

    import java.util.*;
    
    class TypesafeHeterogenousContainer {
        Map<Class<?>, Object> map = new HashMap<Class<?>, Object>();
    
        public <T> T get(Class<T> klass) {
            return klass.cast(map.get(klass));
        }
    
        public <T> void put(Class<T> klass, T thing) {
            map.put(klass, thing);
        }
    }
    
    public class Main {
        public static void main(String args[]) {
            TypesafeHeterogenousContainer thc = new TypesafeHeterogenousContainer();
            thc.put(String.class, "a string");
            thc.put(Integer.class, 5);
            System.out.println(thc.get(String.class)); // prints "a string"
    
            thc.put(String.class, 5); // compile-time error
        }
    }
    

    这并不完全是通过重载实现的,因为这是不可能的,因为Java泛型使用类型擦除。因此,您必须在运行时传递Class<?>对象

    你可以在这本书中或在网上的其他页面上阅读更多关于这方面的内容

    如果你没有这本书,你可以从他2006年在JavaOne上的演讲中读到

  3. # 3 楼答案

    正如Jon Skeet所说,仿制药在这种情况下没有帮助

    您可以查看访问者模式,它在polimorphic参数需要不同方法执行的某些情况下很有帮助。但是要注意:只有当类型层次结构稳定时,它才有帮助

    如果您想要一个类型列表不稳定的泛型处理,或者您不喜欢访问者模式的复杂性,我建议使用Map<Class, ValueProcessor>

    private [static?] Map<Class, ValueProcessor> processors = new HashMap<Class, ValueProcessor>();
    
    // initialization
    processors.put(Integer.class, new ValueProcessor() {
       public void process(Object value) {
          doStuffWith( (Integer) value);
       }
    });
    
    processors.put(Date.class, new ValueProcessor() {
       public void process(Object value) {
          doStuffWith( (Date) value);
       }
    });
    
    // and so on...
    
    public interface ValueProcessor {
       public void process(Object value);
    }
    
  4. # 4 楼答案

    我不确定这段代码的内涵是什么,但也许你想要这样的东西:

    public interface CoolInterface<T> {
       void setOverloadedValue(T o);
    }
    
    public interface ValueProvider<T> {
       T getValue();
    }
    
    public class SomeUncoolClass<T> {
    
       private CoolInterface<? super T> coolGuy;
       private ValueProvider<? extends T> valueProvider;
    
       public void helpMeMethod() {
          coolGuy.setOverloadedValue(valueProvider.getValue());
       }
    }