1前書き

Kotlinプログラミング言語は、Java仮想マシン(JVM)上に構築されています。そのため、可視性修飾子を含め、JVMが課すすべての規則に従う必要があります。

しかしながら、コンパイラと我々のコードが構造化されている方法に関して、言語がこれらの修飾子をどのように実装するかに微妙な微妙な違いがいくつかあります。この記事では、これに関するJavaとKotlinの類似点と相違点をいくつか紹介します。


2視認性モディファイア

可視性修飾子は、コードの他のどの要素が変更中の要素にアクセスできるかを判断するために使用されます。それらは、さまざまな範囲のレベルで、コード内のいくつかの異なる要素に適用されます。これらの規則が適用される方法はこれらの異なる使用法の間でわずかに異なるかもしれません、それは最初は混乱するかもしれません。


2.1. 公開可視性

最も明白な修飾子は

public

です。これはおそらく言語全体で最も頻繁に利用されていることであり、要素が変更されるのを誰が見ることができるかについての追加の制限がないことを意味します。

  • Javaとは異なり、Kotlinでは何もpublicとして宣言する必要はほとんどありません** – 他のものを宣言しない場合はデフォルトの修飾子です。これ以外は、KotlinでもJavaと同じように機能します。


public

修飾子を最上位レベルの要素(パッケージ内で直接宣言された外部クラスまたは関数や変数)に適用すると、他のコードからアクセスできます。

public

修飾子をネストした要素(内部クラス、またはクラス内の関数または変数)に適用すると、コンテナにアクセスできるコードでもこの要素にアクセスできます。

例えば:

class Public {
    val i = 1

    fun doSomething() {
    }
}

クラス

Public

は、コードベース全体のどこからでもアクセスできます。


2.2. プライベートビジビリティ

ほとんどの場合使用される他の修飾子は

private

です。

これは

public

とは正反対の意味を持ちます – 誰もそれにアクセスできないことを意味します。

実際には、** Kotlinでは、同じスコープ内で宣言されたコードだけがアクセスできることを意味します。これは、Kotlinが同じファイル内で複数のトップレベル宣言を許可するという単純な理由から、Javaとは微妙に異なります。それ以外の規則は同じです。例えば:

例えば:

private class Private {
    private val i = 1

    private val doSomething() {
    }
}

クラス

Private

は、同じソースファイル内からのみアクセス可能です。


2.3. 保護された可視性

  • Kotlinの

    protected

    修飾子は、宣言するクラスとサブクラスによってのみ厳密にアクセス可能であることを意味します** 。これは、ほとんどの人がJavaの動作を期待しているのと同じですが、Javaの動作方法とは微妙に異なります。

Javaでは、

protected

修飾子は同じパッケージ内の他のものから要素へのアクセスも許可します。たとえば、次のようなクラスファイルがあるとします。

class A {
    protected val i = 1
}

次のファイルはKotlinでは問題なく動作します。

class B : A() {
    fun getValue() : Int {
        return i
    }
}

次のファイルはJavaでは機能しますが、Kotlinでは機能しません。

class C {
    fun getValue() : Int {
        val a = A()
        return a.i
    }
}

そして、以下はJavaでもKotlinでも動作しません。

class D {
    fun getValue() : Int {
        val a = A()
        return a.i
    }
}

さらに、Kotlinの

protected



は、スーパークラスの

protected

要素をオーバーライドするときのデフォルトの可視性になります。必要に応じてこれを明示的に

public__に変更することができます。これは、何かをpublicとして明示的に宣言する必要がある主な時間です。


2.4. パッケージプライベート/デフォルトの可視性

Javaには、“ package-private”(“ default”とも呼ばれる)として知られるアクセス修飾子があります。これは、要素に修飾子が配置されていないときに使用されます。つまり、同じパッケージ内のどのコードからもアクセスできますが、別のパッケージ内のどのコードからもアクセスできません(サブクラスを含む)。

  • 将来的に変更されるかもしれませんが

    Kotlinは現在このモディファイアをまったくサポートしていません

    。その理由は、それが何の保護も提供していないということです – 誰もが同じパッケージ内でコードを定義し、異なるjarファイルからでも私たちの要素にアクセスすることができます。


2.5. 内部の可視性

Kotlinは、Javaが現在サポートしていないオプション

internal

に新しい修飾子を追加します。 ** この修飾子は、同じhttps://kotlinlang.org/docs/reference/visibility-modifiers.html#modules[module]で宣言されている他の方法で制限されていないコードがこの要素にアクセスできることを意味します。 (モジュールは本質的にJarファイルです。)

これはJavaではhttps://www.osgi.org/[OSGi]のようなものを使って可能ですが、現時点ではその言語にネイティブではありません。 Java 9では、パブリック識別子を選択的にエクスポートできるようにすることで、より実現可能なものにするためのいくつかの概念がもたらされます。

これはAPIと実装を書くための大きな利点を追加します。 APIインターフェースは

public

、メイン実装は

public

クラス、それが依存するすべてのサポートコードは

internal

と書くことができます。これを行うと、外部コードがAPIを通過することを余儀なくされ、内部にアクセスできなくなります。例えば:

package com.baeldung.modifiers

internal class Internal {
}

class Public {
    internal val i = 1

    internal fun doSomething() {
    }
}

クラス

Internal

は、同じモジュール内からのみアクセスできます。

“ val i”



“ fun doSomething()”

は、同じモジュール内からのみアクセスできます。たとえそれらが内部にあるクラスにはどこからでもアクセスできます。


3概要

この記事では、Kotlinの可視性修飾子を見ました。

ほとんどの場合、Kotlinの可視性修飾子ルールは、Javaから期待されるものと同じように機能します。ただし、

internal

スコープの導入という大きな違いがあります。これは大規模プロジェクトには非常に便利です。