Почему никакие статические методы в Интерфейсах, но статические поля и внутренние классы хорошо? [pre-Java8] [дубликат]

Исключение нулевого указателя генерируется, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:

  1. Вызов метода экземпляра объекта null.
  2. Доступ или изменение поля объекта null.
  3. Принимая длину null, как если бы это был массив.
  4. Доступ или изменение слотов null, как если бы это был массив.
  5. Бросок null как будто это было значение Throwable.

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

Ссылка: http://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html

91
задан skaffman 28 June 2015 в 00:31
поделиться

11 ответов

официальное предложение было сделано позволить статические методы в интерфейсах в Java 7. Это предложение вносится под Монета Проекта .

Мое личное мнение - то, что это - прекрасная идея. В реализации нет никакой технической трудности, и это - очень логическая, разумная вещь сделать. Существует несколько предложений в Монете Проекта, что я надеюсь, будет никогда , становятся частью языка Java, но это - то, которое могло очистить много API. Например, Collections класс имеет статические методы для управления любым List реализация; они могли быть включены в эти List интерфейс.

<час>

Обновление: В Подкаст Отряда Java № 234, Joe D'arcy упомянул предложение кратко, говоря, что это было "сложно" и вероятно не сделает его в под Монетой Проекта.

<час>

Обновление: , В то время как они не превращали его в Монету Проекта для Java 7, Java 8 действительно поддерживает статические функции в интерфейсах.

49
ответ дан erickson 24 November 2019 в 06:51
поделиться

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

можно назвать InterfaceName.class для получения Объекта класса, соответствующего интерфейсу, но класс Класса конкретно указывает, что это представляет классы и интерфейсы в JAVA-приложении. Однако сам интерфейс не рассматривают как класс, и следовательно Вы не можете присоединить статический метод.

1
ответ дан MetroidFan2002 24 November 2019 в 06:51
поделиться

Две главных причины приходят на ум:

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

  2. Интерфейсы, как предполагается, не имеют код; это - то, для чего абстрактные классы. Смысл интерфейса должен позволить Вам говорить о возможно-несвязанных-объектах, которые происходят со всеми, имеют определенный набор методов. На самом деле обеспечение реализации тех методов вне границ того, чем интерфейсы предназначаются, чтобы быть.

1
ответ дан Eli Courtwright 24 November 2019 в 06:51
поделиться

Я часто задаюсь вопросом почему статические методы вообще? У них действительно есть свое использование, но методы уровня пакета/пространства имен, вероятно, касались бы 80 из того, для чего используются статические методы.

2
ответ дан Vasil 24 November 2019 в 06:51
поделиться

До Java 5 общее использование для статических полей было:

interface HtmlConstants {
    static String OPEN = "<";
    static String SLASH_OPEN = "</";
    static String CLOSE = ">";
    static String SLASH_CLOSE = " />";
    static String HTML = "html";
    static String BODY = "body";
    ...
}

public class HtmlBuilder implements HtmlConstants { // implements ?!?
    public String buildHtml() {
       StringBuffer sb = new StringBuffer();
       sb.append(OPEN).append(HTML).append(CLOSE);
       sb.append(OPEN).append(BODY).append(CLOSE);
       ...
       sb.append(SLASH_OPEN).append(BODY).append(CLOSE);
       sb.append(SLASH_OPEN).append(HTML).append(CLOSE);
       return sb.toString();
    }
}

Этот предназначенный HtmlBuilder не должен был бы квалифицировать каждую константу, таким образом, это могло использовать , ОТКРЫВАЮТ instead of HtmlConstants. ОТКРОЙТЕ

Using, реализации таким образом в конечном счете сбивают с толку.

Теперь с Java 5, мы имеем импорт, статичный синтаксис для достижения того же эффекта:

private final class HtmlConstants {
    ...
    private HtmlConstants() { /* empty */ }
}

import static HtmlConstants.*;
public class HtmlBuilder { // no longer uses implements
    ...
}
3
ответ дан toolkit 24 November 2019 в 06:51
поделиться

На самом деле иногда существуют причины, которым кто-то может извлечь выгоду из статических методов. Они могут использоваться в качестве методов фабрики для классов, которые реализуют интерфейс. Например, это - причина, у нас есть интерфейс Collection и класс Наборов в openjdk теперь. Таким образом, существуют обходные решения, как всегда - предоставляют другому классу частного конструктора, который будет служить "пространством имен" для статических методов.

3
ответ дан 24 November 2019 в 06:51
поделиться

Цель интерфейсов состоит в том, чтобы определить контракт, не обеспечивая реализацию. Поэтому у Вас не может быть статических методов, потому что у них должна была бы уже быть реализация в интерфейсе, так как Вы не можете переопределить статические методы. Относительно полей, только статичных final fields, позволяются, которые являются, по существу, константами (в 1,5 +, у Вас могут также быть перечисления в интерфейсах). Константы там, чтобы помочь определить интерфейс без магических чисел.

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

6
ответ дан Alexander 24 November 2019 в 06:51
поделиться

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

поля Static там (a) потому что они были там в JDK 1.0, и много изворотливых решений были приняты в JDK 1.0 и (b) статическими заключительными полями в интерфейсах, самая близкая вещь, которую Java имел к константам в то время.

Статические внутренние классы в интерфейсах были позволены, потому что это - чистый синтаксический сахар - внутренний класс - на самом деле ничто, чтобы сделать с родительским классом.

, Таким образом, статические методы не позволяются просто, потому что нет никакого неопровержимого довода, чтобы сделать так; непротиворечивость не достаточно востребована для изменения статус-кво.

, Конечно, это могло быть разрешено в будущих версиях JLS, ничего не повреждая.

40
ответ дан Pi Delport 24 November 2019 в 06:51
поделиться

Никогда нет точки к объявлению статического метода в интерфейсе. Они не могут быть выполнены обычным вызовом MyInterface.staticMethod (). (EDIT:Since, которые длятся предложение, смутили некоторых людей, называть MyClass.staticMethod () выполняет точно реализацию staticMethod на MyClass, который, если MyClass является интерфейсом, не может существовать!) При вызове их путем определения класса с реализацией MyImplementor.staticMethod () тогда необходимо знать фактический класс, таким образом, это не важно, содержит ли интерфейс его или нет.

, Что еще более важно, статические методы никогда не переопределяются, и при попытке сделать:

MyInterface var = new MyImplementingClass();
var.staticMethod();

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

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

Для ответа на некоторые комментарии ниже причина Вы не можете выполниться "result=MyInterface.staticMethod ()", то, что она должна была бы выполнить версию метода, определенного в MyInterface. Но не может быть версии, определенной в MyInterface, потому что это - интерфейс. Это не имеет кода по определению.

14
ответ дан DJClayworth 24 November 2019 в 06:51
поделиться

Причина состоит в том, что все методы, определенные в интерфейсе, абстрактны, объявляете ли Вы явно тот модификатор. Абстрактный статический метод не является допустимой комбинацией модификаторов, так как статические методы не в состоянии быть переопределенными.

относительно того, почему интерфейсы позволяют статические поля. У меня есть чувство, которое нужно считать "функцией". Единственная возможность, о которой я могу думать, состояла бы в том, чтобы сгруппировать константы, которыми будут интересоваться реализации интерфейса.

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

0
ответ дан laz 24 November 2019 в 06:51
поделиться

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

Они - только значения и будут скопированы буквально везде, где они используются во время компиляции, таким образом, Вы никогда на самом деле "называете" статические поля во времени выполнения. Наличие статического метода не имело бы той же семантики, так как это включит вызов интерфейса без реализации, которую не позволяет Java.

0
ответ дан cynicalman 24 November 2019 в 06:51
поделиться
Другие вопросы по тегам:

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