Java: Возвратите класс (Не экземпляр)

Действительно ли возможно возвратить в статическом методе класс? Я объясню...

Я имею:

public class A { public static void blah(){} }
public class B { }

Я хочу создать статический метод в возвратах ведьмы B A. Таким образом, можно сделать:

A.blah();

И

B.getA().blah();

Это, не создавая экземпляр A. Просто используйте его статические методы.

Действительно ли это возможно?

11
задан Matt Ball 1 October 2011 в 15:07
поделиться

9 ответов

Это опровержение ответа @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.

7
ответ дан 3 December 2019 в 03:04
поделиться
public class B { 
    public static A getA(){ return null; }
}

B.getA().blah(); //works!

РЕДАКТИРОВАТЬ

Это правда, что это эквивалентно

B.getA();
A.blah();

За исключением того, что они выглядят совсем по-другому. Представьте, что у вас есть цепочка из них.

Я проверил org.apache.commons.cli.OptionBuilder , и лично я бы не стал так поступать, но у автора есть свой случай. API используется только в начале программы, в одном потоке.

Разработчикам API иногда приходится делать какие-то волшебные ходы, не будьте слишком критичны.

1
ответ дан 3 December 2019 в 03:04
поделиться

Я собираюсь предположить, что причина, по которой вы спрашиваете об этом, заключается в том, что вы хотите, чтобы 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();
}
6
ответ дан 3 December 2019 в 03:04
поделиться

Даже если бы это было возможно, от этого мало толку. Вызов A.blah () не создает экземпляр A . Это статический метод, для которого не нужен экземпляр.

И вы не можете использовать интерфейсы для реализации статических методов. Так для чего это нужно?

2
ответ дан 3 December 2019 в 03:04
поделиться

Нет, это невозможно. У вас есть два варианта:

  1. B.getA () возвращает экземпляр A, а blah () будет нестатическим метод.

  2. Непосредственно вызовите A.blah () .

6
ответ дан 3 December 2019 в 03:04
поделиться

Нет, это невозможно. Вы можете только вернуть ссылку на экземпляр класса. Самое близкое к этому - вернуть ссылку на переменную типа Class. Возникает вопрос: зачем вам это нужно? Какую проблему ты пытаешься решить? Может быть лучшее решение.

2
ответ дан 3 December 2019 в 03:04
поделиться

Вы можете вернуть метод, используя отражение, которое вы можете вызвать () позже. Однако похоже, что вы пытаетесь сделать что-то, что нужно сделать по-другому. Почему вы пытаетесь это сделать?

0
ответ дан 3 December 2019 в 03:04
поделиться

Если вы не хотите иметь экземпляр A , тогда пусть B вызовет blah () напрямую. То есть

class B { 
    void blah() { 
        A.blah();
    } 
}
1
ответ дан 3 December 2019 в 03:04
поделиться

Люди говорят, что это невозможно, и это вроде как верно, но если вы используете 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() для более подробной информации.

Я не пробовал этого, так что вам может понадобиться немного подправить.

4
ответ дан 3 December 2019 в 03:04
поделиться
Другие вопросы по тегам:

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