Можно ли в файле kotlin прописать код на java
У меня есть исходный файл Kotlin, но я хочу перевести его на Java.
Как я могу конвертировать Kotlin в исходный код Java?
Я почти уверен, что для этого еще не создано никакого автоматизированного инструмента. Вы можете построить его первым! Весьма вероятно, что в итоге вы получите уродливый и не поддерживаемый класс Java, который не будет работать, если у вас нет стандартной библиотеки Kotlin в пути к классам. В чем смысл? Рассмотрим переводчик j2objC. Было бы здорово, если бы вы могли сделать kotlin -> Java -> objC Цель кнопки «Декомпилировать» - помочь людям понять, как работает компиляция Kotlin. Генерируемый Java-код не предназначен для использования в качестве реального производственного кода (и для этого он плохо подходит - для начала, он не всегда компилируется . ) @yole, а как насчет того, кто не знает Kotlin или у него есть время на его изучение, и у него есть некоторый пример кода на этом языке, который обладает некоторой функциональностью, которую им необходимо понять, чтобы заставить работать свой код Java?Как сказал @Vadzim, в IntelliJ или Android Studio вам просто нужно сделать следующее, чтобы получить код java от kotlin:
- Menu > Tools > Kotlin > Show Kotlin Bytecode
- Нажмите на Decompile кнопку
- Скопируйте код Java
Обновить:
С последней версией (1.2+) плагина Kotlin вы также можете сделать это напрямую Menu > Tools > Kotlin -> Decompile Kotlin to Java .
@Pacerier Как и большинство декомпилируемых выходов, это, конечно, преобразован из Котлина в Яву. Но это показывает дополнительный код. код, который я даже никогда не писал и не слышал эта опция не включена, она окрашена в серый цвет. Как мне это включить. @VikasPandey, Decompile Kotlin to Java в настоящее время включен только для скомпилированных классов Kotlin .Вы можете скомпилировать Kotlin в байт-код, а затем использовать дизассемблер Java.
Не было никакого автоматизированного инструмента, поскольку я проверил пару месяцев назад (и никаких планов относительно одного AFAIK)
В качестве примечания следует помнить, что обобщенные значения в сгенерированном коде могут вызывать предупреждения компилятора, так как Kotlin допускает некоторые вещи, которых не поддерживает компилятор java. Это все еще работает в байт-коде, хотя. @voddan Я думаю, что он имеет в виду усовершенствованные дженерики, которые не возможны в чистой Java. Преобразованные дженерики @Jire всегда встроены, поэтому с Java они выглядят как обычные ссылки на IntelliJ IDEA 2016.2: Меню / Инструменты / Kotlin / Показать байт-код Kotlin, затем нажмите кнопку «Декомпилировать»Вы можете перейти в Инструменты> Kotlin> Показать байт-код kotlin
Чтобы преобразовать Kotlin исходный файл в Java исходный файл, вам нужно (когда вы находитесь в Android Studio):
Нажмите Cmd - Shift - A на Mac или нажмите Ctrl - Shift - A на компьютере с Windows.
Введите искомое действие: Kotlin Bytecode и выберите Show Kotlin Bytecode из меню.
- Нажмите Decompile кнопку в верхней части Kotlin Bytecode панели.
- Теперь вы получаете декомпилированный файл Java вместе с файлом Kotlin на соседней вкладке:
Я компилирую Kotlin в байт-код, а затем декомпилирую его в Java. Я компилирую с помощью компилятора Kotlin и декомпилирую с помощью cfr .
Это позволяет мне скомпилировать это:
Как отметил @ louis-cad, «источник Kotlin -> байт-код Java -> источник Java» пока является единственным решением.
Но я бы хотел упомянуть способ, который я предпочитаю: использовать декомпилятор Jadx для Android .
Это позволяет увидеть генерируемый код для замыканий, и, как по мне, полученный код «чище», чем код из декомпилятора IntelliJ IDEA.
Обычно, когда мне нужно увидеть исходный код Java любого класса Kotlin, я делаю:
- Сгенерировать apk: ./gradlew assembleDebug
- Откройте apk, используя Jadx GUI: jadx-gui ./app/build/outputs/apk/debug/app-debug.apk
В этом графическом интерфейсе работает базовая функциональность IDE: поиск класса, нажмите, чтобы перейти к объявлению. и т.п.
Также весь исходный код можно сохранить, а затем просмотреть с помощью других инструментов, таких как IntelliJ IDEA.
в моем проекте Kotlin у меня есть некоторые части кода Java, которые я хочу преобразовать в Kotlin. Пункт меню преобразовать файл Java в Kotlin отключен, потому что это не весь файл, который я хочу преобразовать.
Как преобразовать код Java в Kotlin?
нет инструмента для преобразования кода Kotlin в Java. Если вы хотите преобразовать часть файла из Java в Kotlin, самый простой способ-скопировать код из файла Java в IDE и вставить его в файл Kotlin.
С Android Studio 3.0
вы не нужно устанавливать любой плагин для преобразования кода java в код kotlin. Теперь Google официально поддерживает язык Котлин.
- Меню Android Studio ->код - > преобразовать файл Java в файл Kotlin
Перед Android Studio 3.0
Если вы используете старую Android Studio (которая ниже версии 3.0), есть инструмент Котлин под меню.
Установка плагина Kotlin:
- Меню Android Studio ->Файл - > Настройки - > Плагины - > просмотр репозиториев - > Котлин
преобразование кода Java в код Котлина:
- Выберите файл класса java из структуры проекта.
- Меню Android Studio ->код - > преобразовать файл Java в файл Kotlin
Я нашел обходной путь:
- создайте файл Java и вставьте внутри этого файла Java-код, который вы хотите скрыть.
- Теперь скопируйте код Java из файла Java.
- перейдите в файл Kotlin и вставьте этот код. Идея предложит преобразовать код из Java в Kotlin.
для преобразования кода Java в Android studio используйте CTRL+SHIFT+ALT + K
для конвертации с сайта используйте Попробовать Котлин сайт.
для преобразования из Android app использовать мастер в Android.
В Android Studio 3.0
Котлин полностью поддерживается от Android Studio 3.0 (i.e, не требуется плагин Kotlin). Если у вас есть Android Studio > = 3.0 тогда ваши следующие задания очень просты,
- вы можете создать новый файл Kotlin.
- вы можете добавить код Kotlin к существующему Проект.
- вы можете конвертировать весь код JAVA в Kotlin
преобразовать существующие Код Java для кода Kotlin
В Android Studio 3.0 откройте файл Java и выберите код > преобразовать файл Java в файл Kotlin.
или создайте новый файл Kotlin (Файл > Создать > Файл/Класс Котлина), а затем вставьте код Java в этот файл-при появлении запроса нажмите да для преобразования кода в Kotlin. Вы можете проверить Не показывать этот диалог в следующий раз, что позволяет легко сбрасывать фрагменты кода Java в ваш Kotlin файлы.
Примечание:: при создании нового проекта
поставьте галочку напротив включить поддержку Kotlin чтобы получить поддержку Котлина для всего проекта.
ниже приведен снимок экрана первого экрана нового окна создания проекта Android с возможность включить поддержку Kotlin для всего проекта.
при вставке кода Java в файл Kotlin, используя производную IDE IntelliJ, IDE не преобразует Java в Kotlin.
проблема, похоже, связана с IntelliJ, не зная, что код Java. Вот простой способ убедиться, что код преобразуется в Котлин.
- скопируйте код Java из вашего веб-браузера.
- открыть файл нуля (File -> New -> Scratch File или Ctrl+Alt+Shift+Insert)
- в диалоговом окне языки выберите Java в качестве язык.
- вставьте ранее скопированный фрагмент Java.
- выберите Все (Ctrl-A) и скопируйте (Ctrl-C)
- теперь вставьте в свой код Kotlin.
сначала вставив код Java в файл Java scratch, вы дали IntelliJ знать, что фрагмент кода является кодом Java. Затем он автоматически преобразует код в Kotlin при вставке в файл Kotlin.
В Android 3.0 Canary это очень просто: перейдите в код; последний вариант - " конвертировать Java-файл в Kotlin. И вы сделали!
существует также ярлык: Ctrl+Alt+Shift+K
простой Ctrl + Alt + Shift + K код преобразуется в kotlin
Это простой процесс.. перейдите в Панель инструментов Android studio и выполните этот шаг
код - > преобразовать файл java в файл kotlin..
затем он запрашивает подтверждение и перезапускает IDE Android Studio..когда вы подтвердите, он перезагрузит вашу IDE и покажет вам преобразованный файл кода Kotlin.
Если ваша версия Android Studio меньше 3, вам нужно установить плагин Kotlin. Чтобы установить его, следуйте инструкциям ниже link
после установки плагина перезапустите Android Studio и найдите действие ( Ctrl + Shift + A ) и введите преобразовать файл Java в Kotlin.
Поскольку Kotlin был разработан с учетом взаимодействия с Java . Это облегчает использование кода Java изнутри. Класс Kotlin или функция могут ссылаться на классы Java и их методы простым способом.
Методы получения и установки всех типов, определенных в классе Java, представлены как свойства в Kotlin . Следовательно, чтобы получить доступ к получателям и установщикам элемента данных класса Java, он должен ссылаться как свойство внутри Kotlin.
Java-файл объявлен как myjava.java
public class myjava
private int value;
public int getValue()
public void setValue( int value)
this .value = value;
Файл Kotlin объявлен как mykotlin.kt
// файл Kotlin
fun main()
val obj = myjava()
obj.value = 5 // Это вызовет функцию установки
println(obj.value) // Это вызовет функцию получения
Выход:
Java-файл объявлен как myjava.java
public class myjava
public int add( int a, int b)
Колтинский файл объявлен как mykotlin.kt
// файл Kotlin
fun main(args: Array<String>)
val obj = myjava()
val ans = obj.add( 4 , 5 )
println( "The sum of two numbers is " +ans)
Выход:
Например, если в Java-классе XYZ есть метод с именем any, то этот метод можно вызвать в Kotlin как:
Статические члены класса в Java становятся членами объекта-компаньона в Kotlin . Однако эти сопутствующие объекты нельзя использовать непосредственно в выражениях. Для доступа его члены используют полное имя члена, как определено в Java.
Java-файл объявлен как myjava.java
public class myjava
public static void display()
System.out.println( "Call successfull" )
Файл Kotlin объявлен как mykotlin.kt
// объявляем пакет kotlin
// импортируем класс java используя пакет java
fun main(args: Array<String>)
// вызов статического члена класса Java
val str = myjava.display()
Выход:
Kotlin поддерживает инвариантную форму массивов, то есть массивы определенного типа не могут быть назначены массиву типа Any в Kotlin, который отличается от массивов Java, которые могут быть назначены массиву типа Object.
Кроме того, Kotlin не поддерживает присвоение массивов типов подкласса массиву типа суперкласса.
Теперь, поскольку Kotlin не предоставляет массивы для примитивных типов, он предоставляет несколько специализированных классов для представления массива примитивных типов в Java. Эти классы не имеют никакого отношения к классу Array и компилируются в примитивные массивы Java для максимальной производительности. Это преобразование в байт-код не вносит дополнительных затрат, независимо от способа использования массивов.
Java-файл объявлен как myjava.java
public class myjava
public int compute( int [] array)
for ( int a: array)
result = result + a;
Файл Kotlin объявлен как mykotlin.kt
// код Котлина
fun main(args: Array<String>)
val obj = myjava()
val array = intArrayOf( 1 , 2 , 3 , 4 , 5 , 6 )
println( "The sum of an array is " +sum)
Выход:
Java поддерживает концепцию аргументов переменной длины в функциях, т.е. когда число аргументов функции заранее неизвестно, но известен их тип, мы объявляем параметр varargs. Kotlin не предоставляет параметров varargs, однако для полной работы с Java он поддерживает специальный оператор распространения (*) для вызова функций, имеющих параметры varargs.
Java-файл объявлен как myjava.java
public class myjava
public void myfunc(String str, int . numbers)
System.out.println( "Passed string is " + str);
for ( int n : numbers)
Файл Kotlin объявлен как mykotlin.kt
// код Котлина
fun main(args: Array<String>)
val obj = myjava()
val array = intArrayOf( 10 , 20 , 30 )
obj.myfunc( "Geeks" , *array)
Выход:
Типы в Kotlin отличаются от типов в Java. Однако для обеспечения совместимости Kotlin обеспечивает отображение типов Java на типы Kotlin. Это отображение происходит во время компиляции, и никаких существенных изменений в производительности во время выполнения не наблюдается.
Типы примитивов Java отображаются на следующие типы примитивов:
Некоторые из встроенных классов, определенных в пакете java.lang, также отображаются на классы Kotlin.
Типы в штучной упаковке примитивных типов данных Java отображаются в обнуляемые типы в Kotlin.
Ранее вышло две статьи по языку Kotlin. В первой статье мы с вами познакомились с языком, а во второй рассмотрели популярные конструкции, которые могут быть не очевидны для типового Java разработчика.
Цели миграции
Прежде чем внедрять Kotlin в ваш проект давайте определимся каким целям вы следуете. Естественно вы хотите улучшить качество кода, ускорить написание и поддержку части или всей системы. Прежде всего, следует определить о каких масштабах идет речь:
- Вас интересуют только тесты.
- Вас интересует только новая функциональность или часть старого кода.
- Вас интересует полная замена старого кода и дальнейшая разработка.
Чем ниже позиция, тем больше масштаб трагедии.
Если вас интересует пункт 1, то данная статья вам не нужна, для вас будет 4 и 5 часть цикла о Kotlin.
Если вас интересует второй пункт, то нужно понимать, что смесь Java и Kotlin в определенных пропорциях в одном проекте может затормозить вашу работу. Но это при условии сильно смешанного Java и Kotlin кода внутри одного проекта. Об этом ниже.
Третий пункт хорош тем, что у вас не будет проблем с долгой компиляцией, как во втором случае. Однако, это путь самый долгий, но к счастью у нас есть средства автоматизации.
Java + Kotlin
Давайте разберемся как же совместно работают Java и Kotlin с технической стороны. В чем мы уверены? В виртуальной машине! Есть байт-код, который будет исполняться на виртуальной машине Java. Байт-код мы получаем в результате компиляции Java и Kotlin. На итоговой машине может стоять любая версия JVM, а нам подойдет 6, 7 или 8, т.к. Kotlin может быть скомпилирован под одну из них с незначительными ограничениями. Как вы, возможно, знаете, файлы с расширением .java, которые содержат исходный код, компилируются с помощью javac в файлы .class, которые содержат байт-код. Аналогично в случае Kotlin. Файлы с исходным кодом имеют расширение .kt, а файлы с байт-кодом также .class. Компиляция происходит с помощью компилятора kotlinc. На картинке ниже изображен упрощенный процесс сборки приложения с Kotlin.
Как видно выше приложение с Kotlin требует Kotlin Runtime библиотеки. Благодаря ним в приложении становятся доступными стандартные Kotlin классы и расширения.
Полная совместимость означает, что вы можете не только использовать классы Java, но и наследоваться от них, реализовывать интерфейсы, применять Java аннотации в своем Kotlin коде и т.д. Более того, из Java можно вызывать Kotlin код в естественном виде, никаких спец. хаков, ничего лишнего.
На случай, более привычного использования Kotlin библиотек в Java, есть специальные средства для того, чтобы минимизировать отличия Kotlin от Java после сборки. Например, first-class функции на самом деле оборачиваются в сгенерированные классы, но названия этих классов менее звучные, чем, например, StringUtils. Для того, чтобы из Java кода имена сгенерированных Kotlin классов-оберток были привычнее, вы можете использовать конструкцию
Такой код в Java будет выглядеть как вызов
Компилятор Kotlin справляется и в случае множественных зависимостей в коде между языками, а среда разработки Intellij Idea поддерживает автодополнения и другую функциональность не смотря на смешанный код.
Теперь у вас есть представление о том как это работает. Важно отметить, что т.к. компилятор, который обрабатывает связанный код не идеален, как и любой процессинг в такой ситуации, то в проектах в которых и Java, и Kotlin присутствуют в большом объеме может замедлиться разработка. На собственном примере я ощутил как долго среда разработки выполняет автодополнение. Трудно точно локализовать проблему, но она общеизвестна и разработчики языка активно с ней борются.
Инструменты миграции
Вместе с языком Kotlin в цикл разработки входит конвертер из Java в Kotlin. Сразу обратите внимание, что обратной конвертации нет. Хорошо, если у вас есть система контроля версий, например, Git, и вы сможете откатить изменения, если они вас не устроят. Конвертировать можно из меню Code -> Convert Java File to Kotlin File или используйте shortcut Сtrl + Alt + Shift + K.
Важно понимать, что задача конвертера не оптимизировать ваш код, а сделать конвертацию конструкций из Java в Kotlin. По этому то, что получится в результате, обычно, следует обязательно пересмотреть и улучшить с помощью возможностей Kotlin. О проблемах конвертации поговорим в самом конце.
Просмотр байт-кода
В плагин для Kotlin входит функциональность просмотра получающегося байт кода. Для того чтобы его увидеть достаточно в меню Tools -> Kotlin выбрать Show Kotlin Byte code.
Заглянем за кулисы
Давайте посмотрим на особенности байт-кода Kotlin. Там мы можем найти кое что интересное для понимания принципов языка.
Такая замечательная вещь как контроль Nullability привносит с собой не значительный оверхед в виде явной проверки на null. Для примера я приведу пустой метод, который ничего не делает, но требует значение параметра не равный null (напомню, что в случае nullable параметра в Kotlin используется String?).
Для этого метода, кроме RETURN команды, в байт-коде мы увидим явную проверку на null:
В случае, когда параметр может быть равен null, т.е. метод выглядит следующим образом:
из байт кода, естественно, исчезает проверка, но всегда генерируется аннотация Nullable или NotNull (это помогает среде разработки подсвечивать опасное использование переменных, которые могут быть null)
Особенности конвертации
Конвертер не стоит на месте и силами разработчиков языка исправляются всё больше ошибок. Наиболее мажорные из них исправлены к версии 1.1. Тем не менее, конвертированный код не идеален и ниже рассмотрим конвертацию лямбд из Java в Kotlin, а также Stream Api.
Отличие лямбд в Kotlin и Java
Простым языком: лямбда - это кусок кода, который можно сохранить в переменную, он может принимать, возвращать значения или может быть передан в функцию.
Один из приятных моментов, который Kotlin привносит в возможности языка - это inline функции. Проще говоря - компилятор способен встроить код того или иного метода в место вызова и, как следствие, это иногда влечет за собой ускорение, при увеличение размера байт-кода.
Например, код метода main
в результате имеет байт код схожий, но не в точности, с
Однако, такой перформанс хак невозможно сделать в случае, когда, например, лямбду нужно сохранить в качестве значения поля класса.
При нежелании, чтобы ваша лямбда была "заинлайнена" используйте ключевое слово noinline для параметра inline функции.
Рассмотрим результат конвертации лямбды. В Java, обычно, для типичных лямбд используются такие функциональные интерфейсы как Runnable, Supplier, Function и т.д. В Kotlin же, как вы уже знаете, тип лямбды декларируется как (ParamsTypes) -> ReturnType. Изначально мы имеем следующий код:
В результате конвертации мы получаем Kotlin код:
Ключевое слово object - обозначает своего рода singleton, т.к. у класса нет контекста (полей класса), то нет никакого смысла создавать для него новые инстансы.
Для того чтобы метод main из Java был представлен как статический (в Kotlin нет статических методов, для этих целей обычно служит companion object) используется аннотация @JvmStatic.
В версии Kotlin 1.1 всё конвертируется отлично, хотя в прошлых версиях была проблема с конвертацией лямбд.
Stream Api
Как вы знаете, с появлением Java 8 в арсенале разработчика появился мощная возможность. Имя ей Stream Api. Задача, которая решается с его помощью - это обработка коллекции данных в функциональном стиле. При этом код в Java выглядит компактным и хорошо структурированным. В Stream Api есть терминальные операции - это завершающие операции, при достижении которых начинается обработка описанного стрима (forEach, collect, sum и т.д.). Важный момент, стримы в Java исключительно lazy, т.е. выполняются только при достижении терминальной операции, а если её нет, то стрим просто ничего не сделает.
В Kotlin, есть аналог Stream Api, но в отличии от Java есть еще и не lazy обработка. Она доступна прямо на уровне коллекции, например
Прямым аналогом stream являются последовательности. Получить последовательность можно с помощью метода asSequence вызванного на коллекции, а дальше работать аналогично как со стримом.
Обратите внимание, что когда мы используем функцию map для коллекции, то это inline функция, т.е. фактически код будет встроен в место вызова, однако это не верно для функции map у последовательности.
Итак, давайте конвертируем Java stream в Kotlin. Пусть у нас есть исходный код, который должен собирать фразу "hello world !" на Java вот таким изощренным способом.
Бэм! И мы получили не компилируемый код. Как я писал, конвертер не идеален.
Для начала заставим его компилироваться. Для этого подкорректируем его и получим уже компилируемый код
В принципе, задача решается уже верно, но давайте перепишем на нативное использование Kotlin без привязки к Java. Ради красоты и читаемости.
Читайте также: