Вызов статического метода

Мы можем назвать статический метод, не упоминая имя класса в Java?

16
задан polygenelubricants 22 April 2010 в 12:49
поделиться

5 ответов

Да, можете. Ознакомьтесь с статическим импортом . Вы должны указать имя класса в операторе import , но после этого не обязательно. из связанной статьи:

import static java.lang.Math.abs;
import static java.lang.Math.max;

int xDist = abs(destination.getX() - x);
int yDist = abs(destination.getY() - y);
return max(xDist, yDist);

Представлено в Java 5.

35
ответ дан 30 November 2019 в 15:28
поделиться

Да, добавив к Брайану Агню, вы также можете вызывать статические методы через экземпляр этого типа класса.

0
ответ дан 30 November 2019 в 15:28
поделиться

Да, вы можете вызывать статический метод без имени класса. Например, если вы вызываете его в другом статическом методе того же класса.

открытый класс TestStatic {

static void hello()
{
   System.out.println("Hello World");
}
static void hello2()
{
   hello();
   System.out.println("Welcome to java");
}
public static void main(String[] args)
{
   hello2();
}

}

0
ответ дан 30 November 2019 в 15:28
поделиться

Да, вы можете вызвать метод static , не упоминая название класса. Есть import static (точный механизм см. JLS 7.5.4 ), но даже без него, если имя может быть разрешено (см. JLS 15.12.1 для точного механизма) без полной квалификации класса, он будет работать.

Следующий код компилирует и выводит «Hello world!» , как и ожидалось.

import static java.lang.System.out;

public class Test {
   static String greeting() {
      return "Hello world!";
   }
   public static void main(String[] args) {
      out.println(greeting());
   }
}

out в операторе println на самом деле является статическим доступом к полю класса java.lang.System , а не статическим , но, тем не менее, это доступ к статическому члену . welcome () - это вызов статического метода, и имя класса можно опустить, поскольку его ссылка может быть разрешена без полного уточнения имени.


Теперь давайте спросим, ​​хорошая ли это идея. Если только вы не вызываете метод static из его класса, то вообще НЕ рекомендуется опускать имя класса !!!

Давайте сначала сосредоточимся на статическом импорте . Цитата из руководства :

Итак, когда следует использовать статический импорт? Очень экономно! Используйте его только тогда, когда в противном случае у вас возникнет соблазн объявить локальные копии констант или злоупотребить наследованием (Антипаттерн константного интерфейса). Другими словами, используйте его, когда вам требуется частый доступ к статическим членам из одного или двух классов. Если вы злоупотребляете функцией статического импорта, это может сделать вашу программу нечитаемой и не обслуживаемой , загрязняя ее пространство имен всеми импортируемыми вами статическими членами . Читатели вашего кода (включая вас через несколько месяцев после того, как вы его написали) не будут знать, из какого класса происходит статический член. Импорт всех статических членов из класса может быть особенно вредным для удобочитаемости; если вам нужен только один или два члена, импортируйте их по отдельности. При правильном использовании статический импорт может сделать вашу программу более читаемой, удалив шаблон повторения имен классов.

Аргументы усиливаются на следующем примере:

class Base {
    void task1() {
        System.out.println("Base.task1");
    }
    static void task2() {
        System.out.println("Base.task2");
    }
}

class Child extends Base {
    void task1() {
        System.out.println("Child.task1");          
    }
    static void task2() {
        System.out.println("Child.task2");
    }       
}

//....
Base sweetChildOMine = new Child();
sweetChildOMine.task1(); // prints "Child.task1"
sweetChildOMine.task2(); // prints "Base.task2"

Какая неожиданность! Можно подумать, что, поскольку sweetChildOMine имеет ссылку на экземпляр Child , sweetChildOMine.task2 () должен напечатать «Child.task2» , потому что он переопределен классом Child , верно?

НЕПРАВИЛЬНО! Статический метод не может быть переопределен! Его может скрыть только подкласс! Фактически, если вы попытаетесь поступить правильно и добавить аннотацию @Override к task2 , она не будет компилироваться!

Из JLS 15.12.4.4 Найти метод для вызова :

Если режим вызова статический , ссылка на цель не требуется и переопределение не допускается. Вызывается метод m класса T .

Фактически, эта проблема освещена в Java Puzzlers Puzzle 48: Все, что я получаю, статично. Вывод, сделанный в конце головоломки, таков:

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

Лучше всего следовать всем этим рекомендациям вместе, поэтому:

  • Если вы вызываете статический метод в его собственном классе, не подходите
  • В противном случае, квалифицируйте с классом name
    • Если вы делаете это часто в одном классе, рассмотрите статический импорт этого конкретного метода
      • Старайтесь не статический импорт всех членов с *
    • Никогда не уточнять с выражением
  • Не скрывать статический метод; вы не можете @Override это, это только вызовет путаницу

См. также:

20
ответ дан 30 November 2019 в 15:28
поделиться

Да.

class CallStaticMethodTest { 
   public static void staticMethodOne() {
       System.out.println("Static method one");
   }

   // Invoke from a non-static method
   public void instanceMethodOne() {
        staticMethodOne();// Calling static method without mentioning the class name 
   }

   // Invoke from another static method:
   public static void staticMethodTwo() {
       staticMethodOne();
  }
}  
0
ответ дан 30 November 2019 в 15:28
поделиться
Другие вопросы по тегам:

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