Ссылочные статические методы / переменные в Java из экземпляра - PullRequest
4 голосов
/ 17 сентября 2009

Может кто-нибудь объяснить мне, почему java позволяет вам получать доступ к статическим методам и членам из экземпляра? Плохой пример, если у меня есть класс с именем RedShape и у него есть статический метод getColor (), который возвращает «красный», почему java позволяет вам вызывать статический метод из экземпляра RedShape? Мне кажется, что это нарушает некоторые из основных концепций языкового дизайна. По крайней мере, оно должно сопровождаться предупреждением компилятора.

Заранее спасибо.

Edit:

В частности, я спрашиваю о том, когда у вас есть что-то вроде

RedShape test = new RedShape();
test.getColor();

где getColor - статический метод класса RedShape. Это не имеет никакого смысла, так как это разрешено, и не выдает предупреждение компилятора в командной строке через javac. Я вижу, что это «категорически не рекомендуется», но было любопытно, была ли техническая или разумная причина, почему он разрешен за пределами «потому что C ++ позволяет это».

Ответы [ 5 ]

9 голосов
/ 17 сентября 2009

Я не вижу ничего плохого в вызове статического метода из экземпляра. Что в этом плохого? В частности, довольно часто встречаются методы, которые полезны в логике класса, но на самом деле не нужно манипулировать самим экземпляром.

I делает объект для вызова статического метода через ссылку на экземпляр. Классический пример:

Thread thread = new Thread(...);
thread.sleep(5000); // Doesn't do what it looks like

Это происходит с предупреждением компилятора в некоторых IDE - конечно, в Eclipse, если вы включаете его. (Java / Компилятор / Ошибки и предупреждения / Стиль кода / Нестатический доступ к статическому члену.) Лично я считаю , что ошибка в дизайне Java. (Это одна из ошибок, которую C # удалось избежать копирования.)

3 голосов
/ 17 сентября 2009

На самом деле нет никаких причин, почему вы можете это сделать.

Мое единственное предположение было то, что это позволило бы вам переопределить статические методы, но вы не можете .

Если вы попробуете следующий сценарий:

Банан имеет статический метод, называемый «тест» (это печатает «банан») Apple расширяет Banana и «переопределяет» статический метод, называемый «test» (это печатает «apple»)

и вы делаете что-то вроде этого:

public static void main(String[] args) {
    Apple apple = new Apple();
    Banana banana = new Banana();
    Banana base = new Apple();

    apple.test();
    banana.test();
    base.test();
}

В результате получается:

apple
banana
banana

Так эффективно, это довольно бесполезно.

0 голосов
/ 22 октября 2012
public class MyClass {
    public static String myString;
}


public class AnotherClass {
   public void doSomething() {
       doAnotherThing();
   }
   public static doAnotherThing() {
       MyClass.myString = "something";
   }

Здесь мы обращаемся к статической переменной из нестатического метода (косвенно), вызывая статический метод из нестатического метода.

0 голосов
/ 17 сентября 2009

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

Это или потому, что когда вы вызываете метод внутри класса, даже если вам не нужно ставить префикс перед this., компилятор вставляет его (или эквивалентный), в том числе для статических методов. Если статические методы не могут быть вызваны из экземпляров, то, возможно, возникнет проблема с this. на фронте (или вынудит кодеров указывать имя класса на фронте статических методов всякий раз, когда они захотят использовать их в реальном экземпляре).

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

0 голосов
/ 17 сентября 2009

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

Бывают случаи, когда это удобно и не является нарушением языка ОО.

...