Действительно ли возможно возвратить в статическом методе класс? Я объясню...
Я имею:
public class A { public static void blah(){} }
public class B { }
Я хочу создать статический метод в возвратах ведьмы B A
. Таким образом, можно сделать:
A.blah();
И
B.getA().blah();
Это, не создавая экземпляр A
. Просто используйте его статические методы.
Действительно ли это возможно?
Это опровержение ответа @requestable:
public class B {
public static A getA(){ return null; }
}
B.getA().blah(); //works!
Он «работает», но, вероятно, не в том смысле, который вы ожидаете, и, конечно же, бесполезно. Давайте разделим это на две части:
A a = B.getA();
a.blah();
Первый оператор возвращает (в данном случае null) экземпляр A
, а второй оператор игнорирует этот экземпляр и вызывает A.blah ( )
. Итак, эти операторы на самом деле эквивалентны
B.getA();
A.blah();
или (при условии, что getA ()
не имеет побочных эффектов) просто
A.blah();
И вот пример, который более четко иллюстрирует это:
public class A {
public static void blah() { System.err.println("I'm an A"); }
}
public class SubA extends A {
public static void blah() { System.err.println("I'm a SubA"); }
}
public class B {
public static A getA(){ return new SubA(); }
}
B.getA().blah(); //prints "I'm an A".
. .. и это (я надеюсь) иллюстрирует, почему этот подход не решает проблему OP.
public class B {
public static A getA(){ return null; }
}
B.getA().blah(); //works!
РЕДАКТИРОВАТЬ
Это правда, что это эквивалентно
B.getA();
A.blah();
За исключением того, что они выглядят совсем по-другому. Представьте, что у вас есть цепочка из них.
Я проверил org.apache.commons.cli.OptionBuilder
, и лично я бы не стал так поступать, но у автора есть свой случай. API используется только в начале программы, в одном потоке.
Разработчикам API иногда приходится делать какие-то волшебные ходы, не будьте слишком критичны.
Я собираюсь предположить, что причина, по которой вы спрашиваете об этом, заключается в том, что вы хотите, чтобы B возвращал много разных классов с разным поведением, а не только A.
Вы, вероятно, захотите использовать интерфейс для того, что вы делаете вместо этого.
interface IA {
void blah();
}
public class B {
IA getA1() {
return new IA {
void blah() {
...code...
}
}
}
IA getA2() {
...
}
IA getA3() {
...
}
}
myCallingMethod {
B.getA1().blah();
B.getA2().blah();
B.getA3().blah();
}
Даже если бы это было возможно, от этого мало толку. Вызов A.blah ()
не создает экземпляр A
. Это статический метод, для которого не нужен экземпляр.
И вы не можете использовать интерфейсы для реализации статических методов. Так для чего это нужно?
Нет, это невозможно. У вас есть два варианта:
B.getA ()
возвращает экземпляр
A, а blah ()
будет нестатическим
метод.
Непосредственно вызовите A.blah ()
.
Нет, это невозможно. Вы можете только вернуть ссылку на экземпляр класса. Самое близкое к этому - вернуть ссылку на переменную типа Class. Возникает вопрос: зачем вам это нужно? Какую проблему ты пытаешься решить? Может быть лучшее решение.
Вы можете вернуть метод, используя отражение, которое вы можете вызвать () позже. Однако похоже, что вы пытаетесь сделать что-то, что нужно сделать по-другому. Почему вы пытаетесь это сделать?
Если вы не хотите иметь экземпляр A
, тогда пусть B
вызовет blah ()
напрямую. То есть
class B {
void blah() {
A.blah();
}
}
Люди говорят, что это невозможно, и это вроде как верно, но если вы используете API отражения, вы можете сделать что-то близкое к этому.
Вот как вы можете это сделать.
У вас есть класс, который делает это.
public class B {
Class a
public static Class getA(){
return a;
}
}
тогда называть бла ты делаешь:
try{
Method m = B.getA().getDeclaredMethod("blah");
m.invoke(null);//for a static method, you can invoke on null
}
Catch(Exception e){
// see documentation for list of exceptions
}
Так зачем тебе это делать? Ну, если вы сделаете это таким образом, вы можете изменить класс A в так что getA() может вернуть A, B, C или D, все с разными bla() функциями. Я не совсем уверен, какой цели это будет служить, но если вы хотите это сделать, вы можете.
смотри: Class.getDeclaredMethod() и Method.invoke() для более подробной информации.
Я не пробовал этого, так что вам может понадобиться немного подправить.