Как передать тип как параметр метода в Java

В Java, как можно передать тип в качестве параметра (или объявить как переменная)?

Я не хочу передавать экземпляр типа, но самого типа (например, интервал, Строка, и т.д.).

В C# я могу сделать это:

private void foo(Type t)
{
    if (t == typeof(String)) { ... }
    else if (t == typeof(int)) { ... }
}

private void bar()
{
    foo(typeof(String));
}

Существует ли путь в Java, не передавая экземпляр типа t?
Или я должен использовать свои собственные международные константы или перечисление?
Или есть ли лучший путь?

Править: Вот требование для нечто:
На основе типа t это генерирует другое короткое, xml строка.
Код в, если/еще будет очень маленьким (одна или две строки) и будет использовать некоторые частные переменные класса.

71
задан 10 February 2010 в 22:28
поделиться

5 ответов

Вы можете передать Class в.

private void foo(Class<?> cls) {
    if (cls == String.class) { ... }
    else if (cls == int.class) { ... }
}

private void bar() {
    foo(String.class);
}

Обновление : способ ООП зависит от функциональных требований. Лучшим вариантом будет интерфейс, определяющий foo () , и две конкретные реализации, реализующие foo () , а затем просто вызовите foo () для реализации, на которой вы находитесь. рука. Другим способом может быть Map , Action> , которую вы можете вызвать с помощью actions.get (cls) . Это легко комбинировать с интерфейсом и конкретными реализациями: actions.get (cls) .foo () .

98
ответ дан 24 November 2019 в 13:01
поделиться

Ты должен сдать зачет...

private void foo(Class<?> t){
    if(t == String.class){ ... }
    else if(t == int.class){ ... }
}

private void bar()
{
   foo(String.class);
}
9
ответ дан 24 November 2019 в 13:01
поделиться

Если вы хотите передать тип, то эквивалент в Java будет

java.lang.Class

Если вы хотите использовать слабо типизированный метод, вы просто используйте

java.lang.Object

и соответствующий оператор

instanceof

, например

private void foo(Object o) {

  if(o instanceof String) {

  }

}//foo

Однако в Java есть примитивные типы, которые не являются классами (например, int из вашего примера), поэтому вам нужно быть осторожным.

Настоящий вопрос заключается в том, чего вы действительно хотите здесь достичь, иначе на него сложно ответить:

Или есть лучший способ?

5
ответ дан 24 November 2019 в 13:01
поделиться

Вы можете передать экземпляр java.lang.Class, который представляет тип, т.е.

private void foo(Class cls)
0
ответ дан 24 November 2019 в 13:01
поделиться

О, но это уродливый, не объектно-ориентированный код. В тот момент, когда вы видите «if / else» и «typeof», вы должны думать о полиморфизме. Это неправильный путь. Я думаю, что дженерики здесь ваш друг.

Со сколькими типами вы планируете иметь дело?

ОБНОВЛЕНИЕ:

Если вы просто говорите о String и int, вот один из способов сделать это. Начнем с интерфейса XmlGenerator (достаточно «foo»):

package generics;

public interface XmlGenerator<T>
{
   String getXml(T value);
}

И конкретной реализации XmlGeneratorImpl:

    package generics;

public class XmlGeneratorImpl<T> implements XmlGenerator<T>
{
    private Class<T> valueType;
    private static final int DEFAULT_CAPACITY = 1024;

    public static void main(String [] args)
    {
        Integer x = 42;
        String y = "foobar";

        XmlGenerator<Integer> intXmlGenerator = new XmlGeneratorImpl<Integer>(Integer.class);
        XmlGenerator<String> stringXmlGenerator = new XmlGeneratorImpl<String>(String.class);

        System.out.println("integer: " + intXmlGenerator.getXml(x));
        System.out.println("string : " + stringXmlGenerator.getXml(y));
    }

    public XmlGeneratorImpl(Class<T> clazz)
    {
        this.valueType = clazz;
    }

    public String getXml(T value)
    {
        StringBuilder builder = new StringBuilder(DEFAULT_CAPACITY);

        appendTag(builder);
        builder.append(value);
        appendTag(builder, false);

        return builder.toString();
    }

    private void appendTag(StringBuilder builder) { this.appendTag(builder, false); }

    private void appendTag(StringBuilder builder, boolean isClosing)
    {
        String valueTypeName = valueType.getName();
        builder.append("<").append(valueTypeName);
        if (isClosing)
        {
            builder.append("/");
        }
        builder.append(">");
    }
}

Если я запустил это, то получу следующий результат:

integer: <java.lang.Integer>42<java.lang.Integer>
string : <java.lang.String>foobar<java.lang.String>

Я не знаю, было ли это то, что у вас было в уме.

8
ответ дан 24 November 2019 в 13:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: