如何在注释中使用@file:JvmName

时间:2019-01-09 06:59:51

标签: java kotlin static-methods dagger-2

这个问题有关如何为jvm制作有效的静态方法实现。通过有效静态定义,我的意思是没有基本 stateless 伴随对象 jvm静态方法实现。
当我需要为匕首实现静态@Provides方法时(例如"Favor static @Provides methods"建议),我发现了这一要求。让我们考虑下一个例子。


顶级功能有效静态

但是类不能在注解(匕首中的模块)中引用

TestModule.kt

@file:JvmName("TestModule") // <-- does not affect anything in this case
@file:Module // <-- dagger module annotation for generated TestModule class
package com.example

import dagger.Module
import dagger.Provides

/**
 * Effectively jvm static implementation (without rudimentary Companion instance)
 */
@Provides
fun getRunnable(): Runnable = Runnable { println(42) }

TestModule.decompiled.java

package com.example;

import dagger.Module;
import dagger.Provides;
import kotlin.Metadata;
import kotlin.jvm.JvmName;
import org.jetbrains.annotations.NotNull;

@Module
@Metadata(
   mv = {1, 1, 13},
   bv = {1, 0, 3},
   k = 2,
   d1 = {"\u0000\b\n\u0000\n\u0002\u0018\u0002\n\u0000\u001a\b\u0010\u0000\u001a\u00020\u0001H\u0007¨\u0006\u0002"},
   d2 = {"getRunnable", "Ljava/lang/Runnable;", "status"}
)
@JvmName(
   name = "TestModule"
)
public final class TestModule {
   /*
   Instance of stateless companion object is absent - that what we want to achieve 
   */
   @Provides
   @NotNull
   public static final Runnable getRunnable() {
      return (Runnable)null.INSTANCE;
   }
}

在使用端出现问题。 TestComponent.kt

package com.example

import dagger.Component

@Component(modules = [TestModule::class /* This name is not available even in compile time */])
interface TestComponent

基本伴侣对象

当我们用 companion对象定义模块类时,可以在注释中引用它,但是在这种情况下,@JvmStatic方法只是从基本伴侣对象实例委托的方法。

TestModule.kt

package com.example

import dagger.Module
import dagger.Provides

@Module
class TestModule {

    companion object {
        @Provides
        @JvmStatic
        fun getRunnable(): Runnable = Runnable { println(42) }
    }
}

TestModule.decompiled.java

package com.example;

import dagger.Module;
import dagger.Provides;
import kotlin.Metadata;
import kotlin.jvm.JvmStatic;
import kotlin.jvm.internal.DefaultConstructorMarker;
import org.jetbrains.annotations.NotNull;

@Module
@Metadata(
        mv = {1, 1, 13},
        bv = {1, 0, 3},
        k = 1,
        d1 = {"\u0000\f\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0003\b\u0007\u0018\u0000 \u00032\u00020\u0001:\u0001\u0003B\u0005¢\u0006\u0002\u0010\u0002¨\u0006\u0004"},
        d2 = {"Lru/tensor/sbis/status/domain/assembly/TestModule;", "", "()V", "Companion", "status"}
)
public final class TestModule {
    /*
    Rudimentary stateless instance can be effectively omitted 
    */
    public static final TestModule.Companion Companion = new TestModule.Companion((DefaultConstructorMarker)null);

    @Provides
    @JvmStatic
    @NotNull
    public static final Runnable getRunnable() {
        return Companion.getRunnable(); // <-- delegated method call
    }

    @Metadata(
            mv = {1, 1, 13},
            bv = {1, 0, 3},
            k = 1,
            d1 = {"\u0000\u0012\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0002\n\u0002\u0018\u0002\n\u0000\b\u0086\u0003\u0018\u00002\u00020\u0001B\u0007\b\u0002¢\u0006\u0002\u0010\u0002J\b\u0010\u0003\u001a\u00020\u0004H\u0007¨\u0006\u0005"},
            d2 = {"Lru/tensor/sbis/status/domain/assembly/TestModule$Companion;", "", "()V", "getRunnable", "Ljava/lang/Runnable;", "status"}
    )
    public static final class Companion {
        @Provides
        @JvmStatic
        @NotNull
        public final Runnable getRunnable() {
            return (Runnable)null.INSTANCE;
        }

        private Companion() {
        }

        // $FF: synthetic method
        public Companion(DefaultConstructorMarker $constructor_marker) {
            this();
        }
    }
}

问题

如何通过名称来引用Util(匕首模块)类的有效静态无状态实现?

0 个答案:

没有答案