Мы можем назвать статический метод, не упоминая имя класса в Java?
Да, можете. Ознакомьтесь с статическим импортом . Вы должны указать имя класса в операторе 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.
Да, добавив к Брайану Агню, вы также можете вызывать статические методы через экземпляр этого типа класса.
Да, вы можете вызывать статический метод без имени класса. Например, если вы вызываете его в другом статическом методе того же класса.
открытый класс 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();
}
}
Да, вы можете вызвать метод 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: Все, что я получаю, статично. Вывод, сделанный в конце головоломки, таков:
Таким образом, квалифицируйте вызовы
статических
методов с именем класса или не квалифицируйте их вообще, если вы вызываете их из их собственный класс, но никогда не уточняйте их с помощью выражения. Также избегайте скрытия статических методов. Вместе эти рекомендации помогают устранить вводящий в заблуждение вид переопределения с помощью динамической отправки для статических методов.
Лучше всего следовать всем этим рекомендациям вместе, поэтому:
статический
метод в его собственном классе, не подходите статический импорт
этого конкретного метода
статический импорт
всех членов с *
статический
метод; вы не можете @Override
это, это только вызовет путаницу Да.
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();
}
}