Java
Android
Kotlin

kotlinとjavaのアクセス修飾子の関係性

はじめに

kotlinのpublic, internal, protected, privateと、javaのpublic, package private, protected, private がお互いにどう見えているのかを調べました。

まずは、それどれがどのようなアクセス権があるのかを見ていきます。

Javaのアクセス修飾子 (クラスに対する宣言)

public どこからでもアクセス可能
protected 宣言できない
package private 同じパッケージからアクセスできる
private 宣言できない

Javaのアクセス修飾子 (クラスメンバに対する宣言)

public 全てのクラスからアクセス可能
protected サブクラスor同じパッケージのクラスからアクセスできる
package private 同じパッケージのクラスからアクセスできる
private 宣言したクラスからのみアクセスできる

Kotlinのアクセス修飾子 (クラス/トップレベル関数・変数に対する宣言)

public どこからでもアクセス可能
internal 同じモジュール内からアクセスできる
protected 宣言できない
private 宣言したクラスからのみアクセスできる

Kotlinのアクセス修飾子 (クラスメンバに対する宣言)

public 全てのクラスからアクセス可能
internal 同じモジュール内のクラスからアクセスできる
protected サブクラスからのみアクセスできる
private 宣言したファイルからのみアクセスできる

kotlinとjavaにおけるアクセス修飾子の関係性

ここから本題に入っていきます、kotlinのアクセス修飾子をJavaから見た時にどうなるのかを見ていきます。

kotlinのprivateなクラス

kotlinのprivateなクラスは、javaではパッケージプライベートとして見なされます。

A.kt
package com.example.model

private class A(name: String, age: Int, height: Int)

B.java
package com.example.model

public class B {

  public B() {
    A a = new A("taku", 23, 168); // OK
  }
}

C.java
package com.example.ui


public class C {

  public C(){
    A a = new A("taku", 23, 168) // ERROR
  }
}

kotlinのinternal修飾子

Javaにはinternal修飾子はありません。そのため、kotlinでinternalがつけられたものは、Javaからはpublicとして見なされます。しかし、クラスメンバーの場合は難読化されることになります。

A.kt
package com.example.model

internal class A(val name: String, internal val age: Int, private val height: Int)

B.java
package com.example.model

public class B {

  public B() {
    A a = new A("taku", 23, 168); // OK

    a.getName(); // OK

    a.getAge(); // ERROR

    a.getAge$production_sources_for_module_example(); // OK

    a.getHeight(); // ERROR
  }
}