Apa penentu akses default di Java?

108

Saya baru saja mulai membaca buku Java dan bertanya-tanya; penentu akses mana yang default, jika tidak ada yang ditentukan?

bennedich
sumber
Istilah yang benar adalah 'pengubah akses'. Kata 'penentu' tidak muncul di JLS.
Marquis dari Lorne

Jawaban:

116

Visibilitas default dikenal sebagai "package-private" (meskipun Anda tidak dapat menggunakan ini secara eksplisit), yang berarti kolom tersebut dapat diakses dari dalam paket yang sama dengan kelas tersebut.

Seperti yang ditunjukkan mdma, itu tidak benar untuk anggota antarmuka, yang defaultnya adalah "publik".

Lihat Access Specifiers Java

KeatsPeeks
sumber
25
salah - tidak benar untuk anggota antarmuka. akses default kemudian menjadi publik
mdma
2
Ini dikenal sebagai 'paket pribadi' sebenarnya. Situs web pihak ketiga bukanlah referensi normatif. Anda harus mengutip JLS saja.
Marquis dari Lorne
81

Penentu default bergantung pada konteks.

Untuk kelas, dan deklarasi antarmuka, defaultnya adalah paket privat. Ini berada di antara dilindungi dan pribadi, hanya mengizinkan kelas dalam akses paket yang sama. (dilindungi seperti ini, tetapi juga mengizinkan akses ke subclass di luar paket.)

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

   void calc() {  // package private method

   }
}

Untuk anggota antarmuka (bidang dan metode), akses defaultnya adalah publik. Tetapi perhatikan bahwa deklarasi antarmuka itu sendiri secara default adalah paket pribadi.

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

   void method1();     // public abstract
}

Jika kita kemudian memiliki deklarasi

public interface MyInterface2 extends MyInterface
{

}

Kelas yang menggunakan MyInterface2 kemudian dapat melihat field1 dan method1 dari antarmuka super, karena keduanya bersifat publik, meskipun mereka tidak dapat melihat deklarasi MyInterface itu sendiri.

mdma
sumber
1
"Paket pribadi" (terkadang ditulis dalam sumber sebagai /* pp */) hanya nama yang mudah digunakan untuk akses default . Itu bukan nama JLS.
Tom Hawtin - tackline
10
@ Tom - itu benar, JLS menggunakan "akses default". Saya bisa saja menulis "default adalah akses default". Tapi itu sepertinya tidak terlalu membantu!
mdma
16

Jika tidak ada penentu akses yang diberikan, itu adalah akses tingkat paket (tidak ada penentu eksplisit untuk ini) untuk kelas dan anggota kelas. Metode antarmuka secara implisit bersifat publik.

Michael Borgwardt
sumber
9

Visibilitas default (tanpa kata kunci) adalah paket yang artinya akan tersedia untuk setiap kelas yang terletak di paket yang sama.

Catatan samping yang menarik adalah bahwa protected tidak membatasi visibilitas ke subclass tetapi juga ke kelas lain dalam paket yang sama

Johannes Wachter
sumber
8

Itu tergantung pada apa benda itu.

  • Tipe level teratas (yaitu, kelas, enum, antarmuka, dan tipe anotasi yang tidak dideklarasikan di dalam tipe lain) secara default bersifat package-private . ( JLS §6.6.1 )

  • Di kelas, semua anggota (yang berarti bidang, metode, dan deklarasi tipe bertingkat) dan konstruktor secara default bersifat paket-pribadi . ( JLS §6.6.1 )

    • Ketika sebuah kelas tidak memiliki konstruktor yang dideklarasikan secara eksplisit, kompilator akan menyisipkan konstruktor argumen nol default yang memiliki penentu akses yang sama dengan kelas tersebut . ( JLS §8.8.9 ) Konstruktor default biasanya salah saji karena selalu bersifat publik, tetapi dalam kasus yang jarang terjadi, hal itu tidak setara.
  • Dalam enum, konstruktor bersifat pribadi secara default. Memang, pembuat enum harus pribadi, dan merupakan kesalahan untuk menentukannya sebagai publik atau dilindungi. Konstanta enum selalu publik , dan tidak mengizinkan penentu akses apa pun. Anggota enum lainnya adalah paket-privat secara default. ( JLS §8.9 )

  • Dalam antarmuka dan tipe anotasi, semua anggota (sekali lagi, itu berarti bidang, metode, dan deklarasi tipe bertingkat) bersifat publik secara default. Memang, anggota antarmuka dan jenis anotasi harus publik, dan merupakan kesalahan untuk menetapkannya sebagai pribadi atau dilindungi. ( JLS §9.3 hingga 9.5 )

  • Kelas lokal diberi nama kelas yang dideklarasikan di dalam blok metode, konstruktor, atau penginisialisasi. Mereka dicakup ke {.. }blok di mana mereka dideklarasikan dan tidak mengizinkan penentu akses apa pun. ( JLS §14.3 ) Dengan menggunakan refleksi, Anda dapat membuat instance kelas lokal dari tempat lain, dan kelas tersebut bersifat pribadi-paket , meskipun saya tidak yakin apakah detail tersebut ada di JLS.

  • Kelas anonim adalah kelas khusus yang dibuat dengan newmenentukan badan kelas secara langsung dalam ekspresi. ( JLS §15.9.5 ) Sintaksnya tidak mengizinkan penentu akses apa pun. Dengan menggunakan refleksi, Anda dapat membuat instance kelas anonim dari tempat lain, dan keduanya serta konstruktor yang dihasilkan bersifat package-private , meskipun saya tidak yakin apakah detail itu ada di JLS.

  • Instance dan blok penginisialisasi statis tidak memiliki penentu akses pada tingkat bahasa ( JLS §8.6 & 8.7 ), tetapi blok penginisialisasi statis diimplementasikan sebagai metode bernama <clinit>( JVMS §2.9 ), sehingga metode harus, secara internal, memiliki beberapa penentu akses. Saya memeriksa kelas yang dikompilasi oleh javac dan oleh kompiler Eclipse menggunakan editor hex dan menemukan bahwa keduanya menghasilkan metode sebagai paket-pribadi . Namun, Anda tidak dapat memanggil <clinit>()dalam bahasa karena karakter <dan >tidak valid dalam nama metode, dan metode refleksi tertanam kuat untuk menolak keberadaannya, jadi secara efektif penentu aksesnya tidak memiliki akses . Metode ini hanya dapat dipanggil oleh VM, selama inisialisasi kelas.Blok penginisialisasi instans tidak dikompilasi sebagai metode terpisah; kode mereka disalin ke setiap konstruktor, sehingga tidak dapat diakses secara individual, bahkan dengan refleksi.

Boann
sumber
7

default adalah kata kunci yang digunakan sebagai pengubah akses untuk metode dan variabel.
Menggunakan pengubah akses ini akan membuat kelas, variabel, metode, atau konstruktor Anda dapat diakses dari kelas atau paket sendiri, juga akan disetel jika tidak ada pengubah akses.

  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

jika Anda menggunakan default di antarmuka Anda akan dapat menerapkan metode di sana seperti contoh ini

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

Namun itu hanya akan bekerja dari versi 8 Java

Dokumentasi Resmi

Pengubah Akses di Java

Amadeu Antunes
sumber
3

Lihat di sini untuk lebih jelasnya. Standarnya tidak ada yang privat / publik / dilindungi, tetapi spesifikasi akses yang sama sekali berbeda. Ini tidak digunakan secara luas, dan saya lebih suka lebih spesifik dalam definisi akses saya.

Brian Agnew
sumber
3

penentu akses default adalah paket. Kelas dapat mengakses anggota kelas lain dalam paket yang sama. tetapi di luar paket itu tampak sebagai pribadi

abhi
sumber
3

Berikut adalah kutipan tentang visibilitas level paket dari wawancara dengan James Gosling, pencipta Java:

Bill Venners : Java memiliki empat tingkat akses. Standarnya adalah paket. Saya selalu bertanya-tanya apakah membuat default akses paket nyaman karena tiga kata kunci yang sudah diketahui orang-orang dari C ++ adalah pribadi, dilindungi, dan publik. Atau jika Anda memiliki alasan tertentu yang menurut Anda akses paket harus menjadi default.

James Gosling : Paket umumnya adalah sekumpulan hal-hal yang semacam ditulis bersama. Jadi secara umum saya bisa melakukan satu dari dua hal. Salah satunya adalah memaksa Anda untuk selalu memasukkan kata kunci yang memberi Anda domain. Atau saya bisa saja memiliki nilai default. Dan kemudian pertanyaannya adalah, apa yang membuat default yang masuk akal? Dan saya cenderung mencari hal yang paling tidak berbahaya.

Jadi publik akan menjadi hal yang sangat buruk untuk membuat default. Privat mungkin akan menjadi hal yang buruk untuk membuat default, jika hanya karena orang sebenarnya tidak sering menulis metode privat. Dan hal yang sama dengan dilindungi. Dan dalam melihat sekumpulan kode yang saya miliki, saya memutuskan bahwa hal paling umum yang cukup aman ada di dalam paket. Dan C ++ tidak memiliki kata kunci untuk itu, karena mereka tidak memiliki pengertian tentang paket.

Tapi saya lebih menyukainya daripada gagasan teman, karena dengan teman Anda harus menghitung siapa semua teman Anda, jadi jika Anda menambahkan kelas baru ke sebuah paket, maka Anda biasanya harus pergi ke semua kelas. kelas dalam paket itu dan memperbarui teman-teman mereka, yang saya selalu merasa sangat menyebalkan.

Tetapi daftar teman itu sendiri menyebabkan semacam masalah versi. Jadi ada gagasan tentang kelas yang ramah. Dan hal yang menyenangkan yang saya jadikan sebagai default - saya akan menyelesaikan masalah jadi apa kata kuncinya?

Untuk sementara sebenarnya ada kata kunci yang bersahabat. Tetapi karena yang lainnya dimulai dengan "P," itu "ramah" dengan "PH". Tapi itu mungkin hanya di sana untuk sehari.

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

Vitalii Fedorenko
sumber
2

Perbarui penggunaan kata kunci Java 8default : Seperti yang telah dicatat oleh banyak orang. Visibilitas default (tanpa kata kunci)

bidang tersebut akan dapat diakses dari dalam paket yang sama dengan yang dimiliki kelas tersebut.

Jangan bingung dengan fitur Java 8 baru ( Metode Default ) yang memungkinkan sebuah antarmuka menyediakan implementasi ketika diberi label dengan defaultkata kunci.

Lihat: Pengubah akses

Ahmad Sanie
sumber
1

Ada pengubah akses yang disebut "default" di JAVA, yang memungkinkan pembuatan instance langsung dari entitas itu hanya di dalam paket itu.

Ini tautan yang berguna:

Pengubah / Penentu Akses Java

Krishna Ganeriwal
sumber
-2

Pertama-tama izinkan saya mengatakan satu hal tidak ada istilah seperti "Access specifier" di java. Kita harus menyebut semuanya sebagai "Pengubah". Seperti yang kita ketahui bahwa final, static, synchronized, volatile .... disebut sebagai pengubah, bahkan Publik, pribadi, dilindungi, default, abstrak juga harus disebut sebagai pengubah. Default adalah suatu pengubah dimana keberadaan fisik tidak ada tetapi tidak ada pengubah ditempatkan maka itu harus diperlakukan sebagai pengubah default.

Untuk membenarkan ini, ambil satu contoh:

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

Outputnya adalah: Hello Java

Sekarang ubah publik menjadi privat dan lihat kesalahan kompiler apa yang Anda dapatkan: Dikatakan "Modifier privat tidak diizinkan di sini" Kesimpulannya adalah seseorang bisa saja salah atau beberapa tutorial bisa salah tetapi kompiler tidak bisa salah. Jadi kita dapat mengatakan tidak ada istilah penentu akses di java semuanya adalah pengubah.

Sagar Raut
sumber
Kalimat pertama tepat, tetapi fakta bahwa kelas luar tidak bisa menjadi pribadi tidak membuktikan bahwa tidak ada penentu akses di Java.
Marquis dari Lorne
@EJP Ini hanyalah sebuah contoh. Apa yang saya katakan adalah bahwa istilah penentu akses digunakan dalam bahasa lain seperti c, dot net dll, tetapi istilah teknis di java untuk ini adalah pengubah. Jika Anda menggunakan eclipse atau IDE lainnya, Anda dapat melihat bahwa pada saat membuat kelas baru kami diminta untuk memberikan nama pengubah dan dalam daftar mereka menyediakan publik, privat, abstrak, dll
Sagar Raut
Dalam contoh saya apa yang saya coba katakan bahwa kompilator memberikan pesan kesalahan: pengubah pribadi tidak diizinkan, itu tidak memberikan pesan seperti penentu akses pribadi tidak diizinkan. Jadi istilah teknis yang harus kita katakan adalah pengubah di java tidak mengakses penentu di java
Sagar Raut