如何访问反映在kotlin的静态字段?

我在java中有这个抽象类:

abstract class AbsApiTestCase { T mApi; @Before public void setUp() throws Exception { mApi = instanceApi((Class) ( (ParameterizedType) getClass().getGenericSuperclass()) .getActualTypeArguments()[0]); } static  T instanceApi(Class clazz) throws Exception { return new Retrofit.Builder() .baseUrl(clazz.getField("BASE_URL").get(null).toString()) .addConverterFactory(GsonConverterFactory.create( new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create())) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .client(getClient()) .build().create(clazz); } // some code } 

而api看起来像这样:

 public interface GithubApi { String BASE_URL = "https://api.github.com/"; // some code } 

它可以像这样使用:

 public class GithubApiTest extends AbsApiTestCase { // some code } 

但是,当我将我的代码转换为kotlin时,静态字段BASE_URL如下所示:

 interface GithubApi { companion object { val BASE_URL = "https://api.github.com/" } // some code } 

BASE_URL不能像上面那样访问。 我发现有一个@JvmField批注,但Android工作室说JvmField cannot be applied to a property defined in companion object of interface

有没有办法访问这个“静态字段”?

如何使BASE_URL编译时常量?

 interface GithubApi { companion object { const val BASE_URL = "https://api.github.com/" } } 

在字节码级别, BASE_URLGithubApi接口的静态字段。

 public interface GithubApi { public static final GithubApi$Companion Companion; public static final java.lang.String BASE_URL; static {}; Code: 0: new #26 // class GithubApi$Companion 3: dup 4: aconst_null 5: invokespecial #30 // Method GithubApi$Companion."":(Lkotlin/jvm/internal/DefaultConstructorMarker;)V 8: putstatic #32 // Field Companion:LGithubApi$Companion; 11: return } 

我看到了四个基本的选择:

1)将属性提取到对象(伴随或不伴随)中:

 object GithubApiUrls { val BASE_URL = "https://api.github.com/" } 

2)制作一个包级别的属性:

 package myProgram val BASE_URL = "https://api.github.com/" 

3)如果需要inheritance(不知道TBH是什么),可以使用类而不是接口:

 open class GithubApi { val BASE_URL = "https://api.github.com/" } 

4)用接口中的方法替换该字段(可以被覆盖):

 interface GithubApi { fun BaseUrl() = "https://api.github.com/" } 

根本不建议在接口中使用常量。 它引入太多的复杂性而没有真正的价值收益。

尝试从实现接口的实际类中解耦包含常量的类。

 public class AllUrls { public static final String GITHUB_URL = "https://api.github.com/"; } 

这将成为

 object AllUrls { val GITHUB_URL = "https://api.github.com/" } 

并使用它

  static  T instanceApi(Class clazz) throws Exception { return new Retrofit.Builder() .baseUrl(AllUrls.INSTANCE.getGITHUB_URL()) .addConverterFactory(GsonConverterFactory.create( new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create())) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .client(getClient()) .build().create(clazz); } 

@JvmStatic注解将使属性的后台字段是一个静态的。 也就是说,如果将注释应用于伴随对象中的属性,则将在封闭类中创建新的静态字段。

请注意,Kotlin确实没有静态的概念,而且这个注释仅仅是针对JVM语言的可访问性。