Можем ли мы вызвать статический метод без упоминания имени класса в Java?
Вызов статического метода
Ответы (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.
Да, вы можете вызвать метод static
без упоминания имени класса. Вот import static
(см. JLS 7.5.4 для точного механизма), но и без него, если имя может быть разрешено (см. 15.12" rel="nofollow noreferrer">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
на самом деле является static
доступом к полю класса java.lang.System
, не static
метод, но, тем не менее, это static
членский доступ. greeting()
— это вызов метода static
, и имя класса можно опустить, поскольку его ссылка может быть разрешена без полного уточнения имени.
Теперь давайте спросим, хорошая ли это идея. Если вы не вызываете метод static
из его класса, НЕ рекомендуется вообще опускать имя класса!!!
Сначала сосредоточимся на static import
. Цитата из руководства:
Итак, когда следует использовать статический импорт? Очень экономно! Используйте его только тогда, когда у вас возникнет соблазн объявить локальные копии констант или злоупотребить наследованием (антишаблон интерфейса констант). Другими словами, используйте его, когда вам требуется частый доступ к статическим членам одного или двух классов. Если вы злоупотребляете функцией статического импорта, это может сделать вашу программу нечитаемой и непригодной для сопровождения, загрязняя ее пространство имен всеми
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
, верно?
НЕПРАВИЛЬНЫЙ! Метод static
нельзя переопределить! Его можно скрыть только подклассом! На самом деле, если бы вы попытались поступить правильно и добавить аннотацию @Override
к task2
, она бы не скомпилировалась!
Из JLS 15.12.4.4 Найдите метод для вызова< /а>:
Если режим вызова
static
, ссылка на цель не требуется, и переопределение не разрешено. Вызывается метод m класса T.
На самом деле эта проблема описана в Java Puzzlers Puzzle 48: All I Get Является статическим. Вывод, данный в конце головоломки, таков:
Таким образом, уточняйте вызовы
static
методов с помощью имени класса или не уточняйте их вообще, если вы вызываете их из их собственного класса, но никогда не уточняйте их с помощью выражения. Кроме того, избегайте сокрытия статических методов. Вместе эти рекомендации помогают устранить вводящую в заблуждение видимость переопределения с динамической диспетчеризацией для статических методов.
Лучше всего следовать всем этим рекомендациям вместе, поэтому:
- Если вы вызываете метод
static
в его собственном классе, не уточняйте - Otherwise, qualify with the class name
- If you're doing this a lot within one class, consider
static import
of that specific method- Try not to
static import
all members with*
- Try not to
- Никогда не уточняйте выражением
- If you're doing this a lot within one class, consider
- Не прячьте метод
static
; вы не можете@Override
этого, это только вызовет путаницу
Смотрите также:
- Почему Java не позволяет переопределять методы
static
? - Когда вы используете аннотацию Java
@Override
и почему?
Да, добавив к Брайану Агнью, вы также можете вызывать статические методы через экземпляр этого типа класса.
...without mentioning the class name
- person wheaties; 13.04.2010
Да, вы можете вызвать статический метод без имени класса. Например, если вы вызываете его в другом статическом методе того же класса.
открытый класс 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();
}
}
Да.
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();
}
}