Din*_*ian 7 java android java-8 jacoco kotlin
我们有一个带有默认方法的接口,我们在两个Java和Kotlin类中实现了该接口,我们提供了非默认方法的实现.
当我们在调试模式(没有testCoverageEnabled = true)运行时,应用程序按预期工作.但是当我们使用testCoverageEnabled = true在不同的配置中运行时,应用程序崩溃时出现以下错误
java.lang.NoSuchMethodError: No static method $$triggerInterfaceInit()V in class Lcom/ui/viewholders/CAViewContract$$CC; or its super classes (declaration of 'ui.viewholders.CAViewContract$$CC' appears in /data/app/SMCXbiLYvHb1Kk08Kee__g==/base.apk)
at home.c.CCFragment.<clinit>(Unknown Source:0)
at home.HomePageCardProvider.getFragment(HomePageCardProvider.java:17)
at home.HomeFragment.handleCardFragment(HomeFragment.java:172)
Run Code Online (Sandbox Code Playgroud)
注意: 1.JaCoCo版本:"0.8.0"2.操作系统:Android with minSdk 21
如果我们将minSdk更改为24,它testCoverageEnabled = true本身就可以正常工作.我们无法弄清楚确切的问题.
如果您想要调用某个方法的实现,而该方法在您的类中显式地default没有实现,则可能会出现此问题。(但在该基础(父级、超级)中有一个实现)。defaultinterfaceimplementsdefault interfaceinterface
示例:假设这些定义:
class A implements DerivedInterface /*, ...*/ {
@Override public void methodFromBaseInterface() {
DerivedInterface.super.methodFromBaseInterface(); // Error:
// NoSuchMethodError: No static method methodFromBaseInterface
}
// ...
}
interface DerivedInterface extends BaseInterface {
// ...
// `methodFromBaseInterface` hasn't overriden here.
}
interface BaseInterface {
default void methodFromBaseInterface() { /* ...*/ }
// ...
}
Run Code Online (Sandbox Code Playgroud)
然后执行:
A a = new A();
a.methodFromBaseInterface(); // This cause above error!
Run Code Online (Sandbox Code Playgroud)
你会在提到的地方得到一个错误!
(旁注:您可能需要定义至少一种方法DerivedInterface以避免NoClassDefFoundError在运行时获取!)
这类似于一个错误!我们使用了super关键字。为什么是预期的static方法?!!还有一点是,上面的代码没有任何问题,你可以在任何Java 8兼容的环境中运行它,没有任何问题!
我认为这个问题与Android平台中Java 8语言API的不完整支持有关:
Android Studio 3.0 及更高版本支持所有 Java 7 语言功能以及部分 Java 8 语言功能(因平台版本而异)。
特别请参阅该页面中的Java 8 Language API和Compatible minSdkVersion表:
java.lang.FunctionalInterface:API 级别 24 或更高。
DerivedInterface如果您有权访问简单覆盖的定义methodFromBaseInterface并将其显式委托给其super接口:
interface DerivedInterface extends BaseInterface {
@Override default void methodFromBaseInterface() {
BaseInterface.super.methodFromBaseInterface();
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
定义一个class实现它BaseInterface并A从中派生的中间体。然后运行methodFromBaseInterface间接抛出中间class:
class MiddleClass /*extends B*/ implements BaseInterface {}
class A extends MiddleClass implements DerivedInterface {
@Override public void methodFromBaseInterface() {
super.methodFromBaseInterface(); // Indirectly from `MiddleClass`
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
注意:/*extends B*/如果您的A类以前有一个super命名的B.
| 归档时间: |
|
| 查看次数: |
653 次 |
| 最近记录: |