В этой статье нет ничего нового. Я просто собрал несколько тривиальных утверждений, которые могут быть нетривиальными для некоторых программистов младших программистов. Скучные старые вещи.
Если вам случается все это, вы знаете больше о Java, чем обычная домашняя жена. Я не знаю, есть ли смысл знать все это. Вы можете быть довольно хорошим программистом на Java, если не знаете некоторых из этих функций. Однако много новой информации в этой статье, вероятно, указывает на то, что у вас есть возможности для развития.
Есть 4 разных типа защиты
на Яве (не три). Это private
, private
пакеты, protected
и public
. Если вы не укажете какой-либо модификатор защиты при определении элемента в классе, он будет закрытым (не публичным и не защищенным).
С другой стороны, если вы не укажете модификатор защиты перед объявлением метода в интерфейсе: он будет общедоступным. Вы можете указать, что он явно public
но он не влияет на Java, и SONAR не понравится вам.
Мое мнение о Java, позволяющее вам опционально писать public
перед методом в интерфейсе, заключается в том, что это технологическая ошибка.
Точно так же вы можете написать final
перед полем в интерфейсе или даже static
. Это может означать, что они могут быть нестатичными или не финальными: это не так. Поля интерфейса являются окончательными и статическими. Всегда.
Защищенные и частные пакеты не совпадают
Частная защита пакета (или защита по умолчанию) позволит другим классам того же пакета получить доступ к методу или полю. Защищенные методы и поля можно использовать из классов в одном и том же пакете (до сих пор так же, как и в пакете private), и в дополнение к этому его можно использовать из других классов, расширяющих класс, содержащий защищенное поле или метод.
Защищенный переходный
Если существует три пакета a
, b
и c
, каждый из которых содержит класс с именами A
, B
и C
так что B
расширяет A
а C
расширяет B
тогда класс C
может получить доступ к защищенным полям и методам A
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
package a; public class A { protected void a() { } } package b; import a.A; public class B extends A { protected void b() { a(); } } package c; import b.B; public class C extends B { protected void c() { a(); } } |
Интерфейс не может определять защищенные методы
Многие считают, что вы также можете определить protected
методы в интерфейсе. При программировании компилятор делает это быстро и жестко: вы не можете. Кстати, именно поэтому я считаю, что использование public
ключевого слова в интерфейсе является технологической ошибкой: оно заставляет людей думать, что оно также может быть чем-то другим.
Если вы хотите объявить protected
метод в интерфейсе, вы, вероятно, не поняли инкапсуляцию.
Частное не то частное
Закрытые переменные и методы видны внутри модуля компиляции. Если это звучит слишком загадочно: в том же файле Java (почти). Это немного больше, чем «в классе, где они определены». Их также можно увидеть по классам и интерфейсам, которые находятся в одном модуле компиляции. Внутренние и вложенные классы могут видеть приватные поля и методы класса, их окружающего. Однако вмещающие классы могут также видеть закрытые методы и поля классов, которые они включают, до любой глубины.
01
02
03
04
05
06
07
08
09
10
11
|
package a; class Private { private class PrivateInPrivate { private Object object; } Object m() { return new PrivateInPrivate().object; } } |
Этот последний не широко известен. На самом деле это редко полезно.
Частное — это уровень класса, а не объект
Если вы можете получить доступ к переменной или методу, вы можете получить к ней доступ независимо от того, к какому объекту она принадлежит. Если this.a
доступен, тогда доступен another
this.a
если предположить, что another
является экземпляром того же класса. Объекты, которые являются экземплярами одного и того же класса, могут дурачиться с переменными или методами друг друга. Редко имеет смысл иметь такой код, хотя. Исключение из реальной жизни equals()
(генерируемое Eclipse, строки 15 и 18):
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
|
package a; public class PrivateIsClass { private Object object; @Override public boolean equals(Object obj) { if ( this == obj) return true ; if (obj == null ) return false ; if (getClass() != obj.getClass()) return false ; PrivateIsClass other = (PrivateIsClass) obj; if (object == null ) { if (other.object != null ) return false ; } else if (!object.equals(other.object)) return false ; return true ; } } |
Статические классы могут иметь много экземпляров
Классы, которые не должны иметь экземпляров, обычно называются служебными классами. Они содержат только статические поля и статические методы, и единственный конструктор является закрытым и не вызывается ни одним из статических методов класса. В Java 8 такие звери могут быть реализованы в интерфейсах, поскольку в интерфейсах Java 8 могут быть статические методы. Я не уверен, что мы должны использовать эту функцию вместо служебных классов. Я не совсем уверен, что нам вообще следует использовать служебные классы.
Статические классы всегда находятся внутри другого класса (или интерфейса). Это вложенные классы. Они являются статическими и точно так же, как статические методы не могут получить доступ к методам экземпляра и полям класса, так же как статический вложенный класс не может получить доступ к методам и полям экземпляра класса встраивания. Это потому, что вложенные классы не имеют ссылки (указатель, если хотите) на экземпляр класса встраивания. Внутренние классы, в отличие от вложенных, не являются статичными и не могут быть созданы без экземпляра класса внедрения. Каждый экземпляр внутреннего класса имеет ссылку ровно на один экземпляр класса внедрения, и, таким образом, внутренний класс может обращаться к методам и полям экземпляра класса внедрения.
Из-за этого вы не можете создать внутренний класс без экземпляра окружающего класса. Вам не нужно указывать это, хотя, если это текущий объект, иначе this
. В этом случае вы можете написать new
, в данном случае это просто краткая форма для this.new
. В статической среде, например из статического метода, вы должны указать, с каким экземпляром включающего класса должен создаваться внутренний класс. Смотрите строку 10:
01
02
03
04
05
06
07
08
09
10
11
12
|
package a; class Nesting { static class Nested {} class Inner {} void method(){ Inner inner = new Inner(); } static void staticMethod(){ Inner inner = new Nesting(). new Inner(); } } |
Анонимные классы могут получить доступ только к конечным переменным
Когда анонимный класс определен внутри метода, он может обращаться к локальным переменным, если они являются окончательными. Но говорить это расплывчато. Они должны быть объявлены final
и они также должны быть эффективными окончательными. Это то, что выпущено немного в Java 8. Вам не нужно объявлять такие переменные как final
но они все равно должны быть эффективными final.
Зачем вам объявлять что-то окончательное, когда оно должно быть проверено, чтобы быть таким же? Как аргументы метода. Они также должны быть окончательными. Вы говорите, что это не требование Java? Ну, ты прав. Это требование программирования в хорошем стиле.
Ссылка: | Некоторые предложения о Java от нашего партнера JCG Питера Верхаса из блога Java Deep . |