Как явно указать аргументы типа при вызове универсального метода в Java? - PullRequest
2 голосов
/ 03 января 2012

Представьте себе следующий код, написанный на C #:

public class Provider<T>
{
   T GetValue();  // implementation skipped for brevity
}

//

public class Converter<T1, T2>
{
    T2 Convert(T1 value);// implementation skipped for brevity
}

//

public class SomeClass // No Generics Here
{

    public T2 DoSomething<T1, T2>()
    {
        T1 value = new Provider<T1>().GetValue();
        T2 result = new Converter<T1, T2>().Convert(value);

        return result;
    }
}

// and the usage
...
SomeClass some = new SomeClass();
SomeOtherType result = some.DoSomething<SomeType, SomeOtherType>();

Можно ли добиться того же с Java - я хочу знать, как вызывать метод в Java, предоставляя аргументы типа при использовании метода, как описано выше. Я сделал это в .NET, и я знаю, что Java поддерживает ограничения типов и логический вывод, я просто облажался с синтаксисом.

Ответы [ 2 ]

2 голосов
/ 03 января 2012

И провайдер, и конвертер в порядке, ваш метод DoSomething должен быть переписан так:

public <T1, T2> T2 doSomething() {
  T1 value = new Provider<T1>().GetValue();
  T2 result = new Converter<T1, T2>().Convert(value);
  return result;
}

Что можно использовать так:

SomeClass instance = new SomeClass();
Integer something = instance.<String, Integer>doSomething();
1 голос
/ 03 января 2012

Вот класс Java, который использует некоторые Обобщения, которые вы можете использовать в качестве справочных.Действительно, дженерики Java не совсем такие же, как шаблоны C ++ / C #.Но с некоторыми ограничениями и некоторыми утомительными предупреждениями компилятора Java вы можете получить аналогичные шаблоны с помощью Generics в Java.

public class Parameter {

    /* Innerclass used for holding a generic value.
     *
     */
    protected class Value<T> {

        protected T val;

        public void set(T val) {

            this.val = val;
        }

        public T get() {

            return val;
        }
    }

    // Parameter name
    String name;
    // Parameter value
    Value value;


    /* Construct with empty name and value pair.
     * Use the set method for getting something meaningful.
     */
    public Parameter() {}

    /* Construct with name and value pair.
     *
     */
    public <V> Parameter(String name, V value) {

        set(name, value);
    }

    /* Set name and value pair.
     *
     */
    public <V> void set(String name, V value) {

       this.name  = name;
       this.value = new Value();
       this.value.set(value);
    }

    /* Get the parameter name.
     *
     */
    public String getName() {

        return name;
    }

    /* Get the parameter value.
     *
     */
    public <V> V getValue() {

        //! NOTE the caller must be sure that the proper value type is carried out.
        return ((Value<V>) value).get();
    }

    /* Set the parameter value.
     *
     */
    public <V> void setValue(V value) throws Exception {

        //! NOTE the caller must be sure that the proper value type is used.
        if (value.getClass() != this.value.get().getClass() ) {

            throw new Exception( "trying to set an incompatible parameter value" );
        }

        this.value.set(value);
    }

    /* Return the value class.
     * 
     */
    public Class getValueType() {

        return value.get().getClass();
    }
}
...