É possível acessar funções de extensão do código Java?
Eu defini a função de extensão em um arquivo Kotlin.
package com.test.extensions
import com.test.model.MyModel
/**
*
*/
public fun MyModel.bar(): Int {
return this.name.length()
}
Onde MyModel
é uma classe java (gerada). Agora, eu queria acessá-lo no meu código java normal:
MyModel model = new MyModel();
model.bar();
No entanto, isso não funciona. O IDE não reconhecerá o bar()
método e a compilação falhará.
O que o trabalho está usando com uma função estática do kotlin:
public fun bar(): Int {
return 2*2
}
usando import com.test.extensions.ExtensionsPackage
para que meu IDE pareça estar configurado corretamente.
Procurei no arquivo inteiro de interoperabilidade Java a partir dos documentos do kotlin e também pesquisei bastante no Google, mas não consegui encontrá-lo.
O que estou fazendo de errado? Isso é possível?
java
kotlin
extension-function
Lovis
fonte
fonte
import package com.test.extensions.MyModel
?com.test.extensions.ExtensionsPackage
Respostas:
Todas as funções Kotlin declaradas em um arquivo serão compiladas por padrão para métodos estáticos em uma classe dentro do mesmo pacote e com um nome derivado do arquivo de origem Kotlin (primeira letra maiúscula e extensão ".kt" substituídas pelo sufixo "Kt" ) . Os métodos gerados para funções de extensão terão um primeiro parâmetro adicional com o tipo de receptor da função de extensão.
Aplicando-o à pergunta original, o compilador Java verá o arquivo de origem Kotlin com o nome example.kt
como se a seguinte classe Java tivesse sido declarada
Como nada acontece com a classe estendida do ponto de vista Java, você não pode simplesmente usar a sintaxe de pontos para acessar esses métodos. Mas eles ainda podem ser chamados como métodos estáticos Java normais:
A importação estática pode ser usada para a classe ExampleKt:
fonte
bar(model, param1, param2);
A função de extensão de nível superior do Kotlin é compilada como métodos estáticos Java.
Dado arquivo Kotlin
Extensions.kt
no pacote quefoo.bar
contém:O código Java equivalente seria:
A menos que, ou seja,
Extensions.kt
contivesse a linhaNesse caso, a classe estática Java seria nomeada
DemoUtils
No Kotlin, os métodos de extensão podem ser declarados de outras maneiras. (Por exemplo, como uma função de membro ou como uma extensão de um objeto complementar.)
fonte
Eu tenho um arquivo Kotlin chamado NumberFormatting.kt que tem a seguinte função
Em java, eu simplesmente acesso-o sobre o arquivo NumberFormattingKt da seguinte maneira após a importação necessária
import ....extensions.NumberFormattingKt;
fonte
Você sempre pode ver o código Java real que está sendo gerado a partir do seu código Kotlin, acessando
Tools > Kotlin > Show Kotlin Bytecode
e clicando emDecompile
. Isso pode ajudá-lo tremendamente. No seu caso, o código Java ficará assim se você tiverMyModelExtensions.kt
você pode melhorar isso usando
@JvmName
o arquivo que contémbar
:e resultará neste código:
O uso
MyModels
está alinhado com o que o Java Efetivo sugere para classes de utilidade. Você também pode renomear seu método assim:então, do lado do Java, parecerá idiomático:
fonte
Você precisa duplicar suas funções nos arquivos de classe:
Crie um arquivo Kotlin, para ex Utils.kt
Digite o código
OU
No uso do kotlin:
Em Java, use isto:
fonte
Funciona para mim:
Kotlin
Código Java
Meu projeto é um projeto android antigo criado com Java; agora criei o primeiro arquivo kotlin e adicionei extensões String divertidas String.isNotNullOrEmpty (): Boolean {...}
e eu poderia chamá-lo do arquivo java usando: StringUtilsKt.isNotNullOrEmpty (thestring).
Meu nome de arquivo kotlin é StringUtils
fonte
As outras respostas aqui abordam o caso de chamar uma função de extensão localizada no nível superior de um arquivo de pacote Kotlin.
No entanto, meu caso foi que eu precisava chamar uma função de extensão localizada dentro de uma classe. Especificamente, eu estava lidando com um objeto.
A solução é incrivelmente simples .
Tudo o que você precisa fazer é anotar sua função de extensão como
@JvmStatic
e pronto! Seu código Java poderá acessá-lo e usá-lo.fonte
Quando você estende uma classe como esta:
Ele será compilado para isso:
Existem mais exemplos aqui .
fonte
Até onde eu sei, isso não é possível. Pela minha leitura dos documentos de extensões, parece que
cria um novo método com a assinatura
Em seguida, o Kotlin mapeia essa função para chamadas do formulário
myModel.bar()
, onde, sebar()
não for encontrado naMyModel
classe, procura métodos estáticos que correspondam à assinatura e ao esquema de nomes que ele gera. Observe que isso é apenas uma suposição de suas declarações sobre extensões sendo importadas estaticamente e não substituindo métodos definidos. Não cheguei longe o suficiente na fonte deles para ter certeza.Portanto, supondo que o exposto acima seja verdade, não há como as extensões Kotlin serem chamadas a partir de código java antigo simples, pois o compilador verá apenas um método desconhecido sendo chamado em um objeto e com erro.
fonte