Всегда ли instanceof Void возвращает false? - PullRequest
23 голосов
/ 09 июля 2011

Может ли этот метод вернуть true как-нибудь?

public static <T> boolean isVoid(T t)
{
    return t instanceof Void;
}

Ответы [ 4 ]

51 голосов
/ 09 июля 2011

Да, но я уверен, что это не очень полезно:

public static void main(final String[] args) throws Exception {
    final Constructor c = Void.class.getDeclaredConstructors()[0];
    c.setAccessible(true);
    System.out.println(c.newInstance(null) instanceof Void);
}

Класс Void не может быть создан, поэтому обычно вашему коду не требуется иметь дело с Void экземплярами. Приведенный выше фрагмент кода является лишь примером того, какой хаос вы можете испытать при использовании отражения ...; -)

6 голосов
/ 09 июля 2011

Я не понимаю, почему вы бы проверили, является ли значение экземпляром void (или Void), поскольку, как сказано n-й раз, не может быть создан, или даже расширен без взлома с отражением.Однако для более полезной ситуации, если вы хотите знать, относится ли данный Class к типу void, вы бы не использовали instanceof, а вместо этого ваш параметр метода имел бы тип Class<?>.Примером теста может быть:

public class VoidCheckTest {

    public static void main(String...args) throws SecurityException, NoSuchMethodException {
        Class<VoidCheckTest> c = VoidCheckTest.class;

        Method m = c.getMethod("main", String[].class);

        System.out.println(m.getReturnType().getName() + " = " + isVoid(m.getReturnType()));        
    }

    private static boolean isVoid(Class<?> t) {
        return Void.class.isAssignableFrom(t) || void.class.equals(t);
    }
}

, который выдаст

void = true

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

2 голосов
/ 09 июля 2011

Нет:

Constructor<Void> cv = Void.class.getDeclaredConstructor(); 
cv.setAccessible(true); 
Void v = cv.newInstance(); 
System.out.println(v instanceof Void); //-> true
2 голосов
/ 09 июля 2011

Нет. Чтобы сделать его верным, вы должны вызвать его и передать аргумент типа Void. Но конструктор класса Void является закрытым, поэтому его нельзя вызвать. Более того, этот класс является окончательным, поэтому вы даже не можете его расширить. Таким образом, вы не можете создать экземпляр класса Void. Но это необходимо, чтобы ваш метод возвращал true.

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

...