2009-12-19 3 views
10

Возможно ли вернуть в статическом методе класс? Я объясню ...Java: класс возврата (не экземпляр)

у меня есть:

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

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

A.blah(); 

И

B.getA().blah(); 

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

Возможно ли это?

+1

либо прочитайте http://gbracha.blogspot.com/2008/02/cutting-out-static.html, либо изучите C и используйте указатели на функции. –

+0

Не ответ как таковой, но ... Scala использует одиночные объекты вместо статических методов (которые на самом деле не очень объектно-ориентированные). Если бы вы использовали Scala, то вы очень * могли бы делать такие вещи –

ответ

7

Это опровержение @ irreputable отвечают:

public class B { 
    public static A getA(){ return null; } 
} 

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

Он «работает», но, вероятно, не в том смысле, что вы ожидаете, и, конечно, не полезным способом. Давайте разберем это на две части:

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

Первое утверждение возвращает (нуль в данном случае) экземпляр 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.

2

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

2

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

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

6

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

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

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

+0

Возможно, но не рекомендуется. См. Этот ответ http://stackoverflow.com/questions/1932625/java-return-class-not-an-instance/1933573#1933573 –

+1

ничего себе. это удивительно .. – zedoo

1

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

class B { 
    void blah() { 
     A.blah(); 
    } 
} 
6

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

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

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(); 
} 
0

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

4

Люди говорят, что это невозможно, и это вид true, но если вы используете 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 в So, чтобы getA() мог возвращать A, B, C или D, все с различными функциями blah(). Я не совсем уверен, какую цель будет выполнять, но если вы захотите это сделать, вы можете.

см.: Class.getDeclaredMethod() и Method.invoke() для получения дополнительной информации.

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

1
public class B { 
    public static A getA(){ return null; } 
} 

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

EDIT

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

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

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

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

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

+0

+1 для поиска этой лазейки на Java.-1 за то, что вы не предупредили, что этого делать нельзя. BTW, Eclipse генерирует это предупреждение при компиляции этого кода 'Статический метод blah() из типа A должен быть доступен статическим способом'. –

+0

'org.apache.commons.cli.OptionBuilder' использует этот анти-шаблон вызова статических методов для возвращаемых экземпляров. –

+0

Это не лазейка на Java. Это всего лишь пример, который не делает то, что вы думаете, что он делает. См. Мой ответ. –

Смежные вопросы