【问题标题】:Calling kotlin functions which are keywords in java from java?从 java 中调用作为 java 中关键字的 kotlin 函数?
【发布时间】:2017-06-10 00:42:48
【问题描述】:

由于new 在 kotlin 中不是关键字,所以我可以在 kotlin 中具有以下功能。

fun new(): String {
    return "just returns some string"
}

但我无法从 java 调用此函数,因为 new 是 java 中的关键字。我想知道这个函数在java领域是否有一些别名。我没有找到任何可能是此函数别名的 intellij 建议。

编辑 1

我在kotlin中写了如下代码:

fun new(): String {
    return "just returns some string"
}

fun main(args:Array<String>){
    new()
}

我查看了 java 字节码。如下。

// ================MainKt.class =================
// class version 50.0 (50)
// access flags 0x31
public final class MainKt {


  // access flags 0x19
  public final static new()Ljava/lang/String;
  @Lorg/jetbrains/annotations/NotNull;() // invisible
   L0
    LINENUMBER 2 L0
    LDC "just returns some string"
    ARETURN
   L1
    MAXSTACK = 1
    MAXLOCALS = 0

  // access flags 0x19
  public final static main([Ljava/lang/String;)V
    @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0
   L0
    ALOAD 0
    LDC "args"
    INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull (Ljava/lang/Object;Ljava/lang/String;)V
   L1
    LINENUMBER 6 L1
    INVOKESTATIC MainKt.new ()Ljava/lang/String;
    POP
   L2
    LINENUMBER 7 L2
    RETURN
   L3
    LOCALVARIABLE args [Ljava/lang/String; L0 L3 0
    MAXSTACK = 2
    MAXLOCALS = 1

  @Lkotlin/Metadata;(mv={1, 1, 6}, bv={1, 0, 1}, k=2, d1={"\u0000\u0014\n\u0000\n\u0002\u0010\u0002\n\u0000\n\u0002\u0010\u0011\n\u0002\u0010\u000e\n\u0002\u0008\u0003\u001a\u0019\u0010\u0000\u001a\u00020\u00012\u000c\u0010\u0002\u001a\u0008\u0012\u0004\u0012\u00020\u00040\u0003\u00a2\u0006\u0002\u0010\u0005\u001a\u0006\u0010\u0006\u001a\u00020\u0004\u00a8\u0006\u0007"}, d2={"main", "", "args", "", "", "([Ljava/lang/String;)V", "new", "production sources for module Srinivas"})
  // compiled from: Main.kt
}


// ================META-INF/production sources for module Srinivas.kotlin_module =================



 MainKt

这是反编译成java的字节码:

import kotlin.Metadata;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;

@Metadata(
   mv = {1, 1, 6},
   bv = {1, 0, 1},
   k = 2,
   d1 = {"\u0000\u0014\n\u0000\n\u0002\u0010\u0002\n\u0000\n\u0002\u0010\u0011\n\u0002\u0010\u000e\n\u0002\b\u0003\u001a\u0019\u0010\u0000\u001a\u00020\u00012\f\u0010\u0002\u001a\b\u0012\u0004\u0012\u00020\u00040\u0003¢\u0006\u0002\u0010\u0005\u001a\u0006\u0010\u0006\u001a\u00020\u0004¨\u0006\u0007"},
   d2 = {"main", "", "args", "", "", "([Ljava/lang/String;)V", "new", "production sources for module Srinivas"}
)
public final class MainKt {
   @NotNull
   public static final String new() {
      return "just returns some string";
   }

   public static final void main(@NotNull String[] args) {
      Intrinsics.checkParameterIsNotNull(args, "args");
      new();
   }
}

看来,编写一个名为 new 的函数是一个有效的 java 字节码。但是javac 不允许我编译代码。是否有一些注释或编译器标志我可以启用以获取 javac 来编译 java 文件并调用此函数。

【问题讨论】:

  • 如果您不拥有相关的 kotlin 源代码,反射可能会起作用
  • 在这种情况下,具有 pelochos 答案中提到的别名的实用程序.kt 将起作用。看到反射会更慢

标签: kotlin kotlin-interop


【解决方案1】:

对于这类问题,可以使用@JvmName注解。

@JvmName("neww")
fun new(): String {
    return "just returns some string"
}

您传递给它的名称将是您可以用来引用 Java 中的方法的名称:

String s = something.neww();

一般来说,如果您需要与 Java 代码互操作,最好不要使用 Java 关键字作为 Kotlin 标识符。

【讨论】:

  • 只是为了提供信息而问了这个问题。不会写这样的代码。
【解决方案2】:

您可以使用 @JvmName 为要从 Java 中调用的函数提供不同的名称:

@JvmName("myNew")
fun new(): String {
    return "just returns some string"
}

以及在Java中的用法:

String bar = foo.myNew();

【讨论】:

    【解决方案3】:

    由于您尝试使用关键字,编译器将不允许您将其用作方法名称

    我能想到的唯一解决方法是:

    fun new(): String {
        return "just returns some string"
    }
    
    fun notAKeyWord() = new()
    

    所以你可以在你的java代码中使用WhatEverKt.notAKeyWord()

    【讨论】:

      猜你喜欢
      • 2018-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多