【发布时间】:2019-07-21 14:09:13
【问题描述】:
我有两个包:
1. com.test.hidden:
包含一个受保护的接口MyListener和一个公共类FancyClass,其中包含一个用于注册MyListener对象的公共方法:
package com.test.hidden;
public class FancyClass {
public void registerListener(MyListener listener) {
// ...
}
}
package com.test.hidden;
interface MyListener {
void doSomething();
}
2. com.test.myapp:
这里我有一个FancyClass 的实例,我想向它注册一个新的MyListener 对象。
显然这不起作用,因为MyListener 在com.test.myapp 中不可见。我的直觉是在com.test.hidden 中创建一个扩展MyListener 并且是公开的新接口:
package com.test.hidden;
public interface MyListenerWrapper extends MyListener {
@Override
void doSomething();
}
package com.test.myapp
import com.test.hidden.FancyClass
import com.test.hidden.MyListenerWrapper
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
val fc = FancyClass()
fc.registerListener(object : MyListenerWrapper {
override fun doSomething() {
// ...
}
})
}
}
但我收到了IllegalAccessError:
java.lang.IllegalAccessError: Illegal class access: 'com.test.myapp.MainActivity' attempting to access 'com.test.hidden.MyListener' (declaration of 'com.test.myapp.MainActivity' appears in /data/app/com.test.myapp-ZzNlHhuBCCdAEV4QsZHspw==/base.apk)
at com.test.myapp.MainActivity.onCreate(MainActivity.kt:15)
at android.app.Activity.performCreate(Activity.java:7136)
at android.app.Activity.performCreate(Activity.java:7127)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1272)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2899)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3054)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1814)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:280)
at android.app.ActivityThread.main(ActivityThread.java:6710)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
当我将 MyListener 的可见性更改为 public 时,它工作得很好,所以我怀疑 Java 不喜欢增加子接口中接口的可见性。为什么这不起作用以及如何解决?
【问题讨论】:
-
我认为这是 Kotlin 的事情。 Java 通常会允许它。这里问题的症结在于您有一个公开包私有类型的公共方法。
public void registerListener(MyListener listener)。MyListener应该是公共的,或者这个方法应该是包私有的。 其他任何东西都是糟糕的设计。
标签: java kotlin interface visibility