Jaki jest domyślny specyfikator dostępu w Javie?

108

Właśnie zacząłem czytać książkę o Javie i zastanawiałem się; który specyfikator dostępu jest domyślny, jeśli żaden nie został określony?

bennedich
źródło
Właściwy termin to „modyfikator dostępu”. Słowo „specyfikator” nie pojawia się w JLS.
Markiz Lorne

Odpowiedzi:

116

Domyślna widoczność jest znana jako „pakiet-prywatny” (chociaż nie można tego użyć jawnie), co oznacza, że ​​pole będzie dostępne z wnętrza tego samego pakietu, do którego należy klasa.

Jak zauważył mdma, nie jest to jednak prawdą dla członków interfejsu, dla których domyślną wartością jest „public”.

Zobacz specyfikatory dostępu Java

KeatsPeeks
źródło
25
niepoprawne - nieprawda dla członków interfejsu. domyślny dostęp jest wtedy publiczny
mdma
2
W rzeczywistości jest to znane jako „pakiet prywatny”. Witryny internetowe osób trzecich nie są odniesieniami normatywnymi. Powinieneś cytować tylko JLS.
Markiz Lorne
81

Domyślny specyfikator zależy od kontekstu.

W przypadku klas i deklaracji interfejsu wartością domyślną jest pakiet prywatny. Dzieje się to między chronionymi i prywatnymi, umożliwiając dostęp tylko do klas z tego samego pakietu. (chronione jest w ten sposób, ale umożliwia również dostęp do podklas poza pakietem).

class MyClass   // package private
{
   int field;    // package private field

   void calc() {  // package private method

   }
}

W przypadku elementów członkowskich interfejsu (pól i metod) domyślny dostęp jest publiczny. Należy jednak pamiętać, że sama deklaracja interfejsu domyślnie przyjmuje wartość pakietu private.

interface MyInterface  // package private
{
   int field1;         // static final public

   void method1();     // public abstract
}

Jeśli wtedy mamy deklarację

public interface MyInterface2 extends MyInterface
{

}

Klasy używające MyInterface2 mogą wtedy zobaczyć field1 i method1 z super interfejsu, ponieważ są publiczne, nawet jeśli nie widzą deklaracji samego MyInterface.

mdma
źródło
1
„Pakiet prywatny” (czasami zapisywany w źródle jako /* pp */) to tylko wygodna nazwa dla domyślnego dostępu . To nie jest nazwa JLS.
Tom Hawtin - tackline
10
@Tom - to prawda, JLS używa „domyślnego dostępu”. Mógłbym napisać „domyślny jest dostęp domyślny”. Ale to nie wydawało się zbyt pomocne!
mdma
16

Jeśli nie podano specyfikatora dostępu, jest to dostęp na poziomie pakietu (nie ma dla tego jawnego specyfikatora) dla klas i członków klas. Metody interfejsu są niejawnie publiczne.

Michael Borgwardt
źródło
9

Domyślna widoczność (bez słowa kluczowego) to pakiet, co oznacza, że ​​będzie dostępna dla każdej klasy znajdującej się w tym samym pakiecie.

Ciekawostką na marginesie jest to, że protected nie ogranicza widoczności do podklas, ale także do innych klas w tym samym pakiecie

Johannes Wachter
źródło
8

To zależy od tego, o co chodzi.

  • Typy najwyższego poziomu (czyli klasy, wyliczenia, interfejsy i typy adnotacji, które nie są zadeklarowane w innym typie) są domyślnie prywatne dla pakietu . ( JLS §6.6.1 )

  • W klasach wszyscy członkowie (co oznacza pola, metody i deklaracje typów zagnieżdżonych) i konstruktory są domyślnie prywatne dla pakietu . ( JLS §6.6.1 )

    • Gdy klasa nie ma jawnie zadeklarowanego konstruktora, kompilator wstawia domyślny konstruktor o zerowym argumencie, który ma taki sam specyfikator dostępu jak klasa . ( JLS §8.8.9 ) Domyślny konstruktor jest często błędnie określany jako zawsze publiczny, ale w rzadkich przypadkach nie jest to równoważne.
  • W wyliczeniach konstruktory są domyślnie prywatne . Rzeczywiście, konstruktory wyliczenia muszą być prywatne i określanie ich jako publicznych lub chronionych jest błędem. Stałe wyliczeniowe są zawsze publiczne i nie zezwalają na żaden specyfikator dostępu. Inni członkowie wyliczeń są domyślnie prywatni dla pakietów . ( JLS §8.9 )

  • W interfejsach i typach adnotacji wszystkie elementy członkowskie (ponownie oznacza to, że pola, metody i deklaracje typów zagnieżdżonych) są domyślnie publiczne . Rzeczywiście, elementy członkowskie interfejsów i typy adnotacji muszą być publiczne, a określanie ich jako prywatnych lub chronionych jest błędem. ( JLS §9.3 do 9.5 )

  • Klasy lokalne to nazwane klasy zadeklarowane wewnątrz metody, konstruktora lub bloku inicjatora. Są ograniczone do bloku {.. }, w którym są zadeklarowane i nie zezwalają na żaden specyfikator dostępu. ( JLS §14.3 ) Korzystając z refleksji, możesz utworzyć instancje klas lokalnych z innego miejsca i są one pakietami prywatnymi , chociaż nie jestem pewien, czy ten szczegół znajduje się w JLS.

  • Klasy anonimowe to utworzone klasy niestandardowe, newktóre określają treść klasy bezpośrednio w wyrażeniu. ( JLS §15.9.5 ) Ich składnia nie zezwala na żaden specyfikator dostępu. Korzystając z refleksji, możesz tworzyć instancje anonimowych klas z innego miejsca, a zarówno one, jak i ich wygenerowane konstruktory są pakietami prywatnymi , chociaż nie jestem pewien, czy ten szczegół znajduje się w JLS.

  • Instancje i statyczne bloki inicjalizujące nie mają specyfikatorów dostępu na poziomie języka ( JLS, §8.6 i 8.7 ), ale statyczne bloki inicjalizatora są implementowane jako metoda o nazwie <clinit>( JVMS §2.9 ), więc metoda musi wewnętrznie mieć określony specyfikator dostępu. Zbadałem klasy skompilowane przez javac i kompilator Eclipse przy użyciu edytora szesnastkowego i stwierdziłem, że obie generują metodę jako pakiet-prywatny . Jednak nie można wywołać <clinit>()w języku, ponieważ znaki <i >są nieprawidłowe w nazwie metody, a metody odbicia są połączone na stałe, aby zaprzeczyć jego istnieniu, więc efektywnie jego specyfikatorem dostępu jest Instance dostępu nie ma dostępu . Metoda może być wywoływana tylko przez maszynę wirtualną podczas inicjowania klasy.Bloki inicjatora nie są kompilowane jako oddzielne metody; ich kod jest kopiowany do każdego konstruktora, więc nie można uzyskać do nich dostępu indywidualnie, nawet przez odbicie.

Boann
źródło
7

default to słowo kluczowe używane jako modyfikator dostępu do metod i zmiennych.
Użycie tego modyfikatora dostępu sprawi, że twoja klasa, zmienna, metoda lub konstruktor będą dostępne z własnej klasy lub pakietu, zostanie on również ustawiony, jeśli nie ma modyfikatora dostępu.

  Access Levels
    Modifier    Class   Package Subclass  EveryWhere
    public        Y        Y       Y         Y
    protected     Y        Y       Y         N
    default       Y        Y       N         N
    private       Y        N       N         N

jeśli użyjesz domyślnego interfejsu w interfejsie, będziesz mógł zaimplementować tam metodę, taką jak ten przykład

public interface Computer {    
    default void Start() {
        throw new UnsupportedOperationException("Error");
    }    
}

Jednak będzie działać tylko od wersji 8 Java

Oficjalna dokumentacja

Modyfikatory dostępu w Javie

Amadeu Antunes
źródło
3

Więcej informacji znajdziesz tutaj . Domyślnie nie jest to prywatny / publiczny / chroniony, ale zupełnie inna specyfikacja dostępu. Nie jest powszechnie używany i wolę być bardziej szczegółowy w moich definicjach dostępu.

Brian Agnew
źródło
3

domyślnym specyfikatorem dostępu jest pakiet. klasy mogą uzyskiwać dostęp do członków innych klas w tym samym pakiecie, ale poza pakietem jest on widoczny jako prywatny

abhi
źródło
3

Oto cytat o widoczności na poziomie pakietu z wywiadu z Jamesem Goslingiem, twórcą Javy:

Bill Venners : Java ma cztery poziomy dostępu. Wartość domyślna to pakiet. Zawsze zastanawiałem się, czy ustawienie domyślnego dostępu do pakietu było wygodne, ponieważ trzy słowa kluczowe, o których wiedzieli już ludzie z C ++, były prywatne, chronione i publiczne. Lub jeśli miałeś jakiś szczególny powód, dla którego uważasz, że dostęp do pakietu powinien być domyślny.

James Gosling : Pakiet to ogólnie zestaw rzeczy, które są napisane razem. Tak więc ogólnie mogłem zrobić jedną z dwóch rzeczy. Jednym z nich było zawsze umieszczanie słowa kluczowego, które określa domenę. Albo mogłem mieć wartość domyślną. A potem pojawia się pytanie, co sprawia, że ​​rozsądne niewykonanie zobowiązania? I mam tendencję do wybierania najmniej niebezpiecznej rzeczy.

Tak więc wybór domyślny byłby naprawdę zły. Ustawienie domyślne byłoby prawdopodobnie złą rzeczą, choćby dlatego, że ludzie tak naprawdę nie piszą tak często prywatnych metod. I to samo z chronionymi. Patrząc na fragment kodu, który miałem, zdecydowałem, że najpowszechniejsza rzecz, która była w miarę bezpieczna, znajdowała się w pakiecie. A C ++ nie miał do tego słowa kluczowego, ponieważ nie mieli pojęcia o pakietach.

Ale podobało mi się to raczej niż pojęcie przyjaciół, ponieważ z przyjaciółmi musisz w pewnym sensie wyliczać, kim są wszyscy twoi przyjaciele, więc jeśli dodasz nową klasę do pakietu, generalnie musisz przejść do wszystkich zajęcia w tym pakiecie i zaktualizuj swoich przyjaciół, co zawsze uważałem za kompletny wrzód na tyłku.

Ale sama lista znajomych powoduje pewien problem z wersjami. I tak powstała koncepcja przyjaznej klasy. I fajna rzecz, którą zrobiłem jako domyślną - rozwiążę problem, więc jakie powinno być słowo kluczowe?

Przez chwilę istniało przyjazne słowo kluczowe. Ale ponieważ wszystkie inne zaczynają się od „P”, było to „przyjazne” z „PH”. Ale to trwało tylko jeden dzień.

http://www.artima.com/intv/gosling2P.html

Vitalii Fedorenko
źródło
2

Zaktualizuj użycie słowa kluczowego w Javie 8default : jak zauważyło wielu innych Domyślna widoczność (brak słowa kluczowego)

pole będzie dostępne z wnętrza tego samego pakietu, do którego należy klasa.

Nie należy mylić z nową funkcją Java 8 ( metody domyślne ), która umożliwia interfejsowi udostępnianie implementacji, gdy jest oznaczona etykietądefault słowem kluczowym.

Zobacz: Modyfikatory dostępu

Ahmad Sanie
źródło
-2

Przede wszystkim pozwolę sobie powiedzieć, że w Javie nie ma takiego terminu jak „specyfikator dostępu”. Powinniśmy nazywać wszystko „modyfikatorami”. Ponieważ wiemy, że końcowe, statyczne, zsynchronizowane, nietrwałe ... nazywane są modyfikatorami, nawet jako modyfikatory należy nazywać publiczne, prywatne, chronione, domyślne, abstrakcyjne. Domyślny to taki modyfikator, w którym nie ma fizycznej egzystencji, ale nie ma modyfikatorów, wtedy należy go traktować jako modyfikatory domyślne.

Aby to uzasadnić, weź jeden przykład:

public class Simple{  
    public static void main(String args[]){  
     System.out.println("Hello Java");  
    }  
}  

Wynik będzie: Hello Java

Teraz zmień publiczny na prywatny i zobacz, jaki błąd kompilatora otrzymujesz: mówi „Modyfikator prywatny nie jest tutaj dozwolony” Jaki wniosek jest taki, że ktoś może się mylić lub jakikolwiek tutorial może być zły, ale kompilator nie może się mylić. Możemy więc powiedzieć, że w Javie nie ma specyfikatora dostępu terminów, wszystko jest modyfikatorami.

Sagar Raut
źródło
Pierwsze zdanie jest trafne, ale fakt, że klasa zewnętrzna nie może być prywatną, nie dowodzi, że w Javie nie ma czegoś takiego jak specyfikator dostępu.
Markiz Lorne
@EJP To tylko przykład. Chodzi mi o to, że termin specyfikator dostępu jest używany w innych językach, takich jak c, dot net itp., Ale termin techniczny w Javie to modyfikatory. Jeśli używasz eclipse lub innego IDE, możesz zobaczyć, że w momencie tworzenia nowej klasy jesteśmy proszeni o podanie nazw modyfikatorów, a na liście podają one publiczne, prywatne, abstrakcyjne itp.
Sagar Raut
W moim przykładzie to, co próbuję powiedzieć, że kompilator wyświetla komunikat o błędzie: modyfikatory prywatne nie są dozwolone, nie przekazuje komunikatu takiego jak specyfikator dostępu prywatny niedozwolony. Tak więc termin techniczny, który powinniśmy powiedzieć, to modyfikatory w języku java nie mają dostępu do specyfikacji w języku java
Sagar Raut