Является ли вызов статических методов через объект "плохой формой"? Зачем? - PullRequest
13 голосов
/ 25 октября 2011

В недавнем вопросе кто-то спросил о статических методах, и в одном из ответов было указано, что вы обычно называете их примерно так:

MyClassName.myStaticMethod();

В комментариях к этому также говорится, что вы также можете вызывать его через объект с:

MyClassName myVar;
myVar.myStaticMethod();

но это считалось дурным тоном.

Теперь мне кажется, что это может сделать мою жизнь проще, поэтому мне не нужно беспокоиться о том, что статично или нет (a) .

Есть ли проблемы с вызовом статических функций через объект? Очевидно, вы не захотите создать новый объект, просто чтобы назвать его:

Integer xyzzy;
int plugh = xyzzy.parseInt ("42", 10);

Но, если у вас уже есть объект нужного типа, есть ли проблема в при использовании it?


(a) Очевидно, я не могу вызвать нестатический метод с помощью:

MyClassName.myNonStaticMethod();

но это не та проблема, о которой я здесь спрашиваю.

Ответы [ 4 ]

31 голосов
/ 25 октября 2011

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

//in a main method somewhere
Super instance = new Sub();
instance.method();

//...
public class Super {
    public static void method() {
        System.out.println("Super");
    }
}

public class Sub extends Super {
    public static void method() {
        System.out.println("Sub");
    }
}

Ответ в том, что он печатает «Super», потому что статические методы не являются виртуальными. Даже если instance is-a Sub, компилятор может использовать только тип переменной Super. Однако, вызывая метод через instance, а не Super, вы тонко подразумеваете, что он будет виртуальным.

Фактически, разработчик, читающий instance.method(), должен был бы взглянуть на объявление метода (его сигнатуру), чтобы узнать, какой метод на самом деле вызывается. Вы упоминаете

мне кажется, что это может сделать мою жизнь проще, поэтому мне не нужно беспокоиться о том, что статично или нет

Но в вышеприведенном случае контекст на самом деле очень важен!

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

17 голосов
/ 25 октября 2011

Комментарий о плохой форме взят из Соглашения о кодировании для Java

См. http://www.oracle.com/technetwork/java/codeconventions-137265.html#587

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

В вашем конкретном примере вы можете использовать существующее целое число, через которое вызывается parseInt (то есть это разрешено в Java), но это фокусирует читателя на этом конкретном целочисленном объекте. Это может сбивать с толку читателей, и поэтому руководство состоит в том, чтобы избегать этого стиля.

Относительно того, как это облегчает жизнь программиста, переверните его и спросите, что облегчает жизнь на ридере ? Есть два вида методов: экземплярный и статический. Когда вы видите выражение C.m и знаете, что C является классом, вы знаете, что m должен быть статическим методом. Когда вы видите x.m (где x - это экземпляр), вы не можете сказать, но это похоже на метод экземпляра, и поэтому большинство всех резервируют этот синтаксис только для методов экземпляра.

5 голосов
/ 25 октября 2011

Это вопрос общения.Вызов метода для экземпляра подразумевает , что вы действуете с / с этим конкретным экземпляром, а не с / с классом экземпляра.

4 голосов
/ 25 октября 2011

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

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