Исключение нулевого указателя генерируется, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:
null
. null
. null
, как если бы это был массив. null
, как если бы это был массив. null
как будто это было значение Throwable. Приложения должны бросать экземпляры этого класса, чтобы указать на другие незаконные использования объекта null
.
Ссылка: http://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html
официальное предложение было сделано позволить статические методы в интерфейсах в Java 7. Это предложение вносится под Монета Проекта .
Мое личное мнение - то, что это - прекрасная идея. В реализации нет никакой технической трудности, и это - очень логическая, разумная вещь сделать. Существует несколько предложений в Монете Проекта, что я надеюсь, будет никогда , становятся частью языка Java, но это - то, которое могло очистить много API. Например, Collections
класс имеет статические методы для управления любым List
реализация; они могли быть включены в эти List
интерфейс.
Обновление: В Подкаст Отряда Java № 234, Joe D'arcy упомянул предложение кратко, говоря, что это было "сложно" и вероятно не сделает его в под Монетой Проекта.
<час>Обновление: , В то время как они не превращали его в Монету Проекта для Java 7, Java 8 действительно поддерживает статические функции в интерфейсах.
Статические методы связываются с классом. В Java интерфейс не является технически классом, это - тип, но не класс (следовательно, реализации ключевого слова, и интерфейсы не расширяют Объект). Поскольку интерфейсы не являются классами, у них не может быть статических методов, потому что нет никакого фактического класса для присоединения к.
можно назвать InterfaceName.class для получения Объекта класса, соответствующего интерфейсу, но класс Класса конкретно указывает, что это представляет классы и интерфейсы в JAVA-приложении. Однако сам интерфейс не рассматривают как класс, и следовательно Вы не можете присоединить статический метод.
Две главных причины приходят на ум:
Статические методы в Java не могут быть переопределены подклассами, и это - намного большее соглашение для методов, чем статические поля. На практике я даже не хотел переопределить поле в подклассе, но мне переопределенные методы все время. Так наличие статических методов предотвращает класс, реализовывая интерфейс от предоставления его собственной реализации того метода, который в основном побеждает цель использовать интерфейс.
Интерфейсы, как предполагается, не имеют код; это - то, для чего абстрактные классы. Смысл интерфейса должен позволить Вам говорить о возможно-несвязанных-объектах, которые происходят со всеми, имеют определенный набор методов. На самом деле обеспечение реализации тех методов вне границ того, чем интерфейсы предназначаются, чтобы быть.
Я часто задаюсь вопросом почему статические методы вообще? У них действительно есть свое использование, но методы уровня пакета/пространства имен, вероятно, касались бы 80 из того, для чего используются статические методы.
До 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
...
}
На самом деле иногда существуют причины, которым кто-то может извлечь выгоду из статических методов. Они могут использоваться в качестве методов фабрики для классов, которые реализуют интерфейс. Например, это - причина, у нас есть интерфейс Collection и класс Наборов в openjdk теперь. Таким образом, существуют обходные решения, как всегда - предоставляют другому классу частного конструктора, который будет служить "пространством имен" для статических методов.
Цель интерфейсов состоит в том, чтобы определить контракт, не обеспечивая реализацию. Поэтому у Вас не может быть статических методов, потому что у них должна была бы уже быть реализация в интерфейсе, так как Вы не можете переопределить статические методы. Относительно полей, только статичных final fields
, позволяются, которые являются, по существу, константами (в 1,5 +, у Вас могут также быть перечисления в интерфейсах). Константы там, чтобы помочь определить интерфейс без магических чисел.
BTW, нет никакой потребности явно определить static final
модификаторы для полей в интерфейсах, потому что только статические заключительные поля позволяются.
Я собираюсь пойти со своей любимой теорией с этим, который является, что отсутствие непротиворечивости в этом случае является вопросом удобства, а не дизайна или необходимости, так как я не услышал убедительного аргумента, что это имело любой те два.
поля Static там (a) потому что они были там в JDK 1.0, и много изворотливых решений были приняты в JDK 1.0 и (b) статическими заключительными полями в интерфейсах, самая близкая вещь, которую Java имел к константам в то время.
Статические внутренние классы в интерфейсах были позволены, потому что это - чистый синтаксический сахар - внутренний класс - на самом деле ничто, чтобы сделать с родительским классом.
, Таким образом, статические методы не позволяются просто, потому что нет никакого неопровержимого довода, чтобы сделать так; непротиворечивость не достаточно востребована для изменения статус-кво.
, Конечно, это могло быть разрешено в будущих версиях JLS, ничего не повреждая.
Никогда нет точки к объявлению статического метода в интерфейсе. Они не могут быть выполнены обычным вызовом MyInterface.staticMethod (). (EDIT:Since, которые длятся предложение, смутили некоторых людей, называть MyClass.staticMethod () выполняет точно реализацию staticMethod на MyClass, который, если MyClass является интерфейсом, не может существовать!) При вызове их путем определения класса с реализацией MyImplementor.staticMethod () тогда необходимо знать фактический класс, таким образом, это не важно, содержит ли интерфейс его или нет.
, Что еще более важно, статические методы никогда не переопределяются, и при попытке сделать:
MyInterface var = new MyImplementingClass();
var.staticMethod();
в правилах для помех говорится, что метод, определенный в заявленном типе var, должен быть выполнен. Так как это - интерфейс, это невозможно.
можно, конечно, всегда удалять статическое ключевое слово из метода. Все будет хорошо работать. Вам, вероятно, придется подавить некоторые предупреждения, если это называют от метода экземпляра.
Для ответа на некоторые комментарии ниже причина Вы не можете выполниться "result=MyInterface.staticMethod ()", то, что она должна была бы выполнить версию метода, определенного в MyInterface. Но не может быть версии, определенной в MyInterface, потому что это - интерфейс. Это не имеет кода по определению.
Причина состоит в том, что все методы, определенные в интерфейсе, абстрактны, объявляете ли Вы явно тот модификатор. Абстрактный статический метод не является допустимой комбинацией модификаторов, так как статические методы не в состоянии быть переопределенными.
относительно того, почему интерфейсы позволяют статические поля. У меня есть чувство, которое нужно считать "функцией". Единственная возможность, о которой я могу думать, состояла бы в том, чтобы сгруппировать константы, которыми будут интересоваться реализации интерфейса.
я соглашаюсь, что непротиворечивость была бы лучшим подходом. Никаким статическим участникам нельзя разрешить в интерфейсе.
Только статические заключительные поля могут быть объявлены в интерфейсе (во многом как методы, которые общедоступны, даже если Вы не включаете "общедоступное" ключевое слово, статические поля являются "окончательными" с или без ключевого слова).
Они - только значения и будут скопированы буквально везде, где они используются во время компиляции, таким образом, Вы никогда на самом деле "называете" статические поля во времени выполнения. Наличие статического метода не имело бы той же семантики, так как это включит вызов интерфейса без реализации, которую не позволяет Java.