數(shù)天前我將我java開(kāi)發(fā)的工程,全部轉(zhuǎn)換成了kotlin形式的工程。如果你也想做,本身也有一定的java開(kāi)發(fā)安卓程序的功底。本文將比較適合你。
創(chuàng)建kotlin工程,拷貝類文件xml文件等核心文件到工程目錄下,形成一個(gè)kotlin底子的java代碼組成的工程,然后通過(guò)ctrl +shift +alt +k 快捷代碼逐個(gè)轉(zhuǎn)換為kotlin。轉(zhuǎn)換的結(jié)果相對(duì)比較成功。將轉(zhuǎn)換中遇到的問(wèn)題總結(jié)如下。
1. 循環(huán),改成filter map的使用
那些只是聽(tīng)說(shuō)過(guò)kotlin的小白,在轉(zhuǎn)換前,請(qǐng)參考:最適合Android程序員的kotlin筆記——集合操作
很多普通的操作,AS可以幫我們自動(dòng)轉(zhuǎn),但是唯獨(dú)集合(AS工具的薄弱環(huán)節(jié))這里可以優(yōu)化的比較多。所以建議熟悉。
2. 字符串非空判斷改成kotlin形式。
快捷鍵轉(zhuǎn)換后,還是equal("")形式,改成純正的kotlin風(fēng)格:
一下方法為kotlin特有:
.isEmpty()
.isBlank()
.isEmptyOrNull()
.isNullOrBlank()
類似的,點(diǎn)出來(lái),自己看用那個(gè)合適。
3. 不必要的bindview
原來(lái)的:
@BindView(R.id.ad_image)
ImageView ad_image;
@BindView(R.id.countdownProgressView)
TextView countdownProgressView;
問(wèn)題: 類似此類的代碼,轉(zhuǎn)換后還會(huì)存在。
解決辦法: 轉(zhuǎn)換前,對(duì)齊控件的變量名和id名。轉(zhuǎn)換后,直接刪掉。
你會(huì)驚奇的發(fā)現(xiàn),.kt 文件直接引用了xml文件。代碼中可以直接使用id來(lái)對(duì)view進(jìn)行操作了。
4.丑陋的equals
if (!StringUtils.equals(password, password2)) {
toast(resources.getString(R.string.two_password_input_error))
return
}
改成等號(hào),不等號(hào)。
java中的 equals ,kotlin中可用 == 替代,java中的比較對(duì)象的引用,kotlin中,用===替代。
5. 容易錯(cuò)轉(zhuǎn)的map
在進(jìn)行此類型的轉(zhuǎn)換和修正前,請(qǐng)百度一下kotlin map集合操作。
以下是原java代碼:
private String getTypemane(int id) {
String aa = "";
List<Map<Integer, String>> typelist = listDataSaveUtil.getDataList();
Map<Integer, String> map = typelist.get(0);
for (Map.Entry<Integer, String> str : map.entrySet()) {
if (String.valueOf(id).equals(str.getKey() + "")) {
aa = str.getValue();
}
}
return aa;
}
ktlin錯(cuò)誤轉(zhuǎn)換為:
private fun getTypemane(id: Int): String {
var aa = ""
val typelist = listDataSaveUtil!!.getDataList<Map<Int, String>>()
val map = typelist[0]
for ((key, value) in map) {
if (id == key) {
aa = value
}
}
return aa
}
運(yùn)行報(bào)錯(cuò),不能將int 轉(zhuǎn)number,我給他改成了:
private fun getTypemane(id: Int): String {
var aa = ""
val typelist = listDataSaveUtil!!.getDataList<Map<Int, String>>()
val map = typelist[0]
if(map.contains(id)){
aa=map.getValue(id)
}
return aa
}
6.不夠清爽的if else 轉(zhuǎn)換
java代碼:
private void isShowRv(AllTypeBean body) {
if (getAreaList(body).size() == 1) {
mRvArea.setVisibility(View.GONE);
} else {
mRvArea.setVisibility(View.VISIBLE);
}
if (body.getClassX().size() == 1) {
mRvStyle.setVisibility(View.GONE);
} else {
mRvStyle.setVisibility(View.VISIBLE);
}
if (body.getType().size() == 1) {
mRvAllTvStyle.setVisibility(View.GONE);
} else {
mRvAllTvStyle.setVisibility(View.VISIBLE);
}
if (body.getYear().size() == 1) {
mRvYear.setVisibility(View.GONE);
} else {
mRvYear.setVisibility(View.VISIBLE);
}
}
使用快捷鍵轉(zhuǎn)換,怎么結(jié)果還是一堆if?!!
還是難看,能否用when(kotlin最擅長(zhǎng)的)改造下,動(dòng)手,效果如下:
when {
getAreaList(body!!).size == 1 -> mRvArea!!.visibility = View.GONE
getAreaList(body!!).size != 1 -> mRvArea!!.visibility = View.VISIBLE
body!!.classX!!.size == 1 -> mRvStyle!!.visibility = View.GONE
body.classX!!.size != 1 -> mRvStyle!!.visibility = View.VISIBLE
body!!.type!!.size == 1 -> mRvAllTvStyle!!.visibility = View.GONE
body.type!!.size != 1 -> mRvAllTvStyle!!.visibility = View.VISIBLE
body!!.year!!.size == 1 -> mRvYear!!.visibility = View.GONE
body.year!!.size != 1 -> mRvYear!!.visibility = View.VISIBLE
}
運(yùn)行,程序業(yè)務(wù)邏輯出錯(cuò)?。。。?,斷點(diǎn)研究發(fā)現(xiàn),代碼只走到when中第二行,就break了。后面沒(méi)走。好傻!生手!
正確的寫法:如下:
when {
getAreaList(body!!).size == 1 -> mRvArea!!.visibility = View.GONE
getAreaList(body!!).size != 1 -> mRvArea!!.visibility = View.VISIBLE
}
when {
body!!.classX!!.size == 1 -> mRvStyle!!.visibility = View.GONE
body.classX!!.size != 1 -> mRvStyle!!.visibility = View.VISIBLE
}
when {
body!!.type!!.size == 1 -> mRvAllTvStyle!!.visibility = View.GONE
body.type!!.size != 1 -> mRvAllTvStyle!!.visibility = View.VISIBLE
}
when {
body!!.year!!.size == 1 -> mRvYear!!.visibility = View.GONE
body.year!!.size != 1 -> mRvYear!!.visibility = View.VISIBLE
}
一堆when,不爽。能否再簡(jiǎn)化下,聰明的你一定想到了,還是用回if else
if在 java中是語(yǔ)句,kotlin中是表達(dá)式(表達(dá)式有值,語(yǔ)句不返回值)
改?。?/p>
mRvArea!!.visibility = if (getAreaList(body!!).size == 1) View.GONE else View.VISIBLE
mRvStyle!!.visibility = if (body!!.classX!!.size == 1) View.GONE else View.VISIBLE
mRvAllTvStyle!!.visibility = if (body!!.type!!.size == 1) View.GONE else View.VISIBLE
mRvYear!!.visibility = if (body!!.year!!.size == 1) View.GONE else View.VISIBLE
總結(jié): when結(jié)構(gòu),替換的時(shí)候,典型的場(chǎng)景應(yīng)該是switch case 那種(一旦某一個(gè)條件滿足,直接跳出函數(shù)體)
普通的if根據(jù)需求,千萬(wàn)別像我一樣轉(zhuǎn)錯(cuò)了。但是如果是連續(xù)的else if結(jié)構(gòu),也可以替換。
if (customView != null) {
hideCustomView()
} else if (wv_web_view!!.canGoBack()) {
wv_web_view!!.goBack()
} else {
finish()
}
轉(zhuǎn)成如下:
when{
customView != null-> hideCustomView()
wv_web_view!!.canGoBack()-> wv_web_view!!.goBack()
else->finish()
}
還有這種單if的垃圾代碼,都很適合轉(zhuǎn)when
注意這種單if和上面的單if的不同,這正是我這個(gè)條目想強(qiáng)調(diào)的部分。
if (VipType == HdVipType) {
userMessage!!.vip!!.isHdvip = true
}
if (VipType == DlanVipType) {
userMessage!!.vip!!.isDlanvip = true
}
改動(dòng)秘訣:
看是否能轉(zhuǎn)換為else if 能轉(zhuǎn)換成else if的 ,在轉(zhuǎn)when,遵循這個(gè)原則。
7、漏失的toString()
例子:
private Map<Integer, String> getIntegerStringMap(HomeTypeBean body) {
Map<Integer, String> map = new HashMap<>();
for (HomeTypeBean.TypeBean categoryBean : body.getType()) {
map.put(categoryBean.getType_id(), categoryBean.getType_name());
}
return map;
}
轉(zhuǎn)換Kotlin后:
private fun getIntegerStringMap(body: HomeTypeBean): Map<Int, String> {
val map = HashMap<Int, String>()
for (categoryBean in body.type!!) {
map[categoryBean.type_id] = categoryBean.type_name
}
return map
}
編譯器出現(xiàn)報(bào)錯(cuò)將for循環(huán)中map一行,下劃線標(biāo)紅。
private fun getIntegerStringMap(body: HomeTypeBean): Map<Int, String> {
val map = HashMap<Int, String>()
for (categoryBean in body.type!!) {
map[categoryBean.type_id] = categoryBean.type_name.toString()
}
return map
}
原來(lái)是沒(méi)有添加toString(); 這種情況,as有報(bào)錯(cuò),并有提示。但此處Studio給出的提示不易懂,注意!
8. 集合的轉(zhuǎn)換不夠徹底:
例子java代碼:
private List<String> bornTypeList(HomeTypeBean body) {
List<String> typeList = new ArrayList<>();
for (HomeTypeBean.TypeBean categoryBean : body.getType()) {
typeList.add(categoryBean.getType_name());
}
return typeList;
}
as工具轉(zhuǎn)換為kotlin代碼后:
private fun bornTypeList(body: HomeTypeBean): List<String> {
val typeList = ArrayList<String>()
for (categoryBean in body.type!!) {
typeList.add(categoryBean.type_name.toString())
}
return typeList
}
太丑了,羞于使用,優(yōu)化,代碼如下:
private fun bornTypeList(body: HomeTypeBean): List<String> {
return body.type!!.map { it.type_name.toString() }
}
9. 失靈的onclick
使用bindview的條件下,如下轉(zhuǎn)換后的kotlin代碼,出現(xiàn)業(yè)務(wù)問(wèn)題,點(diǎn)擊事件失靈:
@OnClick(R.id.searcher_view, R.id.play_history_image, R.id.all)
fun onClick(v: View) {
//搜索
if (v === searcher_view) {
ActivityUtils.startActivity(Intent(activity, SearcherActivity::class.java))
return
}
//播放記錄
if (v === play_history_image) {
ActivityUtils.startActivity(PlayHistoryActivity::class.java)
return
}
//全部
if (v === all) {
val intent = Intent(activity, AllTypeActivity::class.java)
intent.putExtra(ConstantUtils.TYPE_NAME, videoType)
intent.putExtra(ConstantUtils.TYPE_ID, typeId)
ActivityUtils.startActivity(intent)
}
}
10. 無(wú)法優(yōu)雅轉(zhuǎn)換的單例
在java中我有如下代碼:
public class DataBeanModel {
private SparseArray<List<PlayVosBean.VodsBean.DataBean>> listHashMap = new SparseArray<>();
private static class SingletonHolder {
private static final DataBeanModel INSTANCE = new DataBeanModel();
}
private DataBeanModel() {
}
public static final DataBeanModel getInstance() {
return SingletonHolder.INSTANCE;
}
public void clearAll(){
listHashMap.clear();
}
public void putValue(int Page, ArrayList<PlayVosBean.VodsBean.DataBean> dataBeans){
listHashMap.put(Page, dataBeans);
}
public List<PlayVosBean.VodsBean.DataBean> getSetByPage(int position){
return listHashMap.get(position);
}
public SparseArray<List<PlayVosBean.VodsBean.DataBean>> getAll(){
return listHashMap;
}
}
as工具轉(zhuǎn)換后:
class DataBeanModel private constructor() {
val all = SparseArray<List<PlayVosBean.VodsBean.DataBean>>()
private object SingletonHolder {
private val INSTANCE = DataBeanModel()
}
fun clearAll() {
all.clear()
}
fun putValue(Page: Int, dataBeans: ArrayList<PlayVosBean.VodsBean.DataBean>) {
all.put(Page, dataBeans)
}
fun getSetByPage(position: Int): List<PlayVosBean.VodsBean.DataBean> {
return all.get(position)
}
companion object {
val instance: DataBeanModel
get() = SingletonHolder.INSTANCE
}
}
已經(jīng)非常臃腫,濃濃的java式kotlin,怎么辦?
正確的做法:
- 注釋和單例相關(guān)的方法:
private static class SingletonHolder {
private static final DataBeanModel INSTANCE = new DataBeanModel();
}
private DataBeanModel() {
}
public static final DataBeanModel getInstance() {
return SingletonHolder.INSTANCE;
}
- 按下ctrl shift alt k 轉(zhuǎn)換成kotlin,將類關(guān)鍵字class 替換為Object
- 刪除注釋部分
object DataBeanModel {
val all = SparseArray<List<PlayVosBean.VodsBean.DataBean>>()
fun clearAll() {
all.clear()
}
fun putValue(Page: Int, dataBeans: ArrayList<PlayVosBean.VodsBean.DataBean>) {
all.put(Page, dataBeans)
}
fun getSetByPage(position: Int): List<PlayVosBean.VodsBean.DataBean> {
return all.get(position)
}
}
- 調(diào)用的部分,改為(中間加INSTANCE):
DataBeanModel.INSTANCE.clearAll();
值得注意的是,當(dāng)我在運(yùn)行業(yè)務(wù)邏輯的時(shí)候,提示我,getSetByPage 這個(gè)方法: return all.get(position)
這個(gè)代碼,里面all已經(jīng)強(qiáng)制要求為空。導(dǎo)致我程序報(bào)錯(cuò)。不知道all為什么會(huì)為空?;貪L吧。
10. 無(wú)法正確轉(zhuǎn)換+=1
我有如下java代碼:
newHost = appMessageBean.getHostUrlList().get(hostPosition += 1);
直接as轉(zhuǎn)換后,在代碼下面直接爆紅。
解決方案:在外面寫hostPosition+=1, 然后再用as工具轉(zhuǎn)換,正確代碼。
hostPosition = hostPosition + 1
newHost = appMessageBean!!.hostUrlList!![hostPosition]
11. 變異的trim方法:
我在java中的trim方法,kotlin轉(zhuǎn)換為了如下形式:
result.addProperty("mobile", etPhone!!.text.toString().trim { it <= ' ' })
注意:kotlin的trim()方法意思發(fā)生了變異,是指去除前后的空格。和java中的trim方法等價(jià)的就是:.trim { it <= ' ' } 轉(zhuǎn)換并沒(méi)有發(fā)生錯(cuò)誤,慢慢學(xué)習(xí)吧。編譯器的快捷鍵轉(zhuǎn)換是正確的。這個(gè)給編譯器點(diǎn)個(gè)贊。
12. 不夠優(yōu)雅的工具類
kotlin中,方法不一定會(huì)寫在類內(nèi)部。操作方法,
- 工具類去掉類的包裹,直接全部都是方法
- 類文件的第一行,指明名字即可,如下:
@file:JvmName("AesUtils")
package com.play.myapplication.helper
- java文件中該怎么用怎么用
- 如果是在kotlin文件中,直接寫方法即可,前面的“類點(diǎn)”也給省略了
13. 錯(cuò)誤轉(zhuǎn)換的get 方法。
默認(rèn)as的轉(zhuǎn)換工具,會(huì)對(duì),get 開(kāi)頭的方法,進(jìn)行重新梳理。
有以下java代碼:
/**
* 標(biāo)題欄id
*/
protected abstract int getTitleBarId();
/**
* 引入布局
*/
protected abstract int getLayoutId();
用來(lái)子類復(fù)寫,父類回調(diào)。結(jié)果AS自動(dòng)轉(zhuǎn)換:
/**
* 標(biāo)題欄id
*/
protected abstract val titleBarId: Int
/**
* 引入布局
*/
protected abstract val layoutId: Int
荒唐呀,我這個(gè)是一個(gè)父類方法,子類需要復(fù)寫。這時(shí)候就會(huì)導(dǎo)致更多的轉(zhuǎn)換異常,解決辦法,在java階段,改成重命名成其他(比如got)開(kāi)頭的方法。然后再用工具轉(zhuǎn)換。
注意不要用get set開(kāi)頭,除非確定是當(dāng)成成員處理。
13. 不夠優(yōu)雅的弱引用。
有弱引用代碼,轉(zhuǎn)換后,累贅不夠優(yōu)雅,并且
弱引用使用處,如下的位置,還會(huì)爆紅。
weakReference.get().setAppMessageBeanFromSP()
添加雙感嘆號(hào)。
weakReference.get()!!.setAppMessageBeanFromSP()
爆紅解決,單仍不夠優(yōu)雅。
解決方案:
采用委托機(jī)制處理
第一步,創(chuàng)建weak類:
class Weak<T : Any>(initializer: () -> T?) {
var weakReference = WeakReference<T?>(initializer())
constructor() : this({
null
})
operator fun getValue(thisRef: Any?, property: KProperty<*>): T? {
return weakReference.get()
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T?) {
weakReference = WeakReference(value)
}
}
第二步
生命的地方這樣寫,
var act:MyActivity? by Weak()
引用的地方:
act.setAppMessageBeanFromSP()
14. 意外的問(wèn)號(hào)
OkGoUtils.postRequest(ConstantUtils.getUrlConstant().getaskvip, JsonObject.toString(), new JsonCallBack<UserandVip>(UserandVip.class, this) {
@Override
public void onSuccess(Response<UserandVip> response) {
}
)}
轉(zhuǎn)換完之后,給我添加一個(gè):
OkGoUtils.postRequest<UserandVip>(
ConstantUtils.getUrlConstant().getaskvip,
JsonObject.toString(),
object : JsonCallBack<UserandVip**?**>(
*UserandVip::class.java, this*
) {
*override fun onSuccess*(response: Response<UserandVip>) {
super.onSuccess(response)
}
)}
很奇怪,導(dǎo)致斜體的部分都在飄紅。
去掉問(wèn)號(hào)就可以了。這里沒(méi)必要if null
15. 錯(cuò)誤轉(zhuǎn)換的json文件:重要#############巨坑巨坑#################

之前我們項(xiàng)目中存在一個(gè)簽到的問(wèn)題,原來(lái)里面是用json轉(zhuǎn)換的,字段是signin , 使用kotlin轉(zhuǎn)換后,kotlin自動(dòng)會(huì)為boolean類型的字段加上is,變成如上圖所示,結(jié)果倒是json變換的時(shí)候,請(qǐng)求返回的bean中,接收不到新的數(shù)據(jù)singin=true。獲取的isSignin=false。破壞了原來(lái)代碼的邏輯。大罪大罪?。。。。。。。。。。。。。。。?!轉(zhuǎn)換方法要坑滿才能明白過(guò)來(lái)呀
16. 點(diǎn)擊事件
源代碼:
btn_stop_dlan.setOnClickListener(this::onClick);
btn_iv_dlan_full.setOnClickListener(this::onClick);
btn_iv_add_volume.setOnClickListener(this::onClick);
btn_iv_delete_volume.setOnClickListener(this::onClick);
btn_ad_x.setOnClickListener(this::onClick);
iv_pause_ad.setOnClickListener(this::onClick);
btn_video_tv.setOnClickListener(this::onClick);
btn_video_hd.setOnClickListener(this::onClick);
btn_video_next.setOnClickListener(this::onClick);
btn_video_skip.setOnClickListener(this::onClick);
rl_close_father.setOnClickListener(this::onClick);
rl_pause_father.setOnClickListener(this::onClick);
rl_close_father.setOnClickListener(this::onClick);
btn_video_start.setOnClickListener(this::onClick);
轉(zhuǎn)換后的代碼:
但是下面報(bào)紅線
btn_stop_dlan.setOnClickListener(OnClickListener { v: View ->
onClick(
v
)
})
btn_iv_dlan_full.setOnClickListener(OnClickListener { v: View ->
onClick(
v
)
})
btn_iv_add_volume.setOnClickListener(OnClickListener { v: View ->
onClick(
v
)
})
btn_iv_delete_volume.setOnClickListener(OnClickListener { v: View ->
onClick(
v
)
})
btn_ad_x.setOnClickListener(OnClickListener { v: View ->
onClick(
v
)
})
17. 缺失的hanlder類型
java代碼(減縮版)
private Handler mDialogHandler;
public void initTimerDialog() {
btn_btn_finish_0.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mDialogHandler.removeCallbacksAndMessages(null);
}
});
};
快捷鍵轉(zhuǎn)換(減縮版)
private var mDialogHandler: Handler? = null
fun initTimerDialog() {
btn_btn_finish_0!!.setOnClickListener(object : OnClickListener {
override fun onClick(v: View) {
mDialogHandler.removeCallbacksAndMessages(null)
}
})
}
轉(zhuǎn)換后:此行報(bào)錯(cuò)!
mDialogHandler.removeCallbacksAndMessages(null)
訂正:
(mDialogHandler as Handler).removeCallbacksAndMessages(null)
Alt+enter中有,只要合理選擇就行。
第二個(gè)坑:
簡(jiǎn)化后的java代碼如下:
public Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
String s = msg.obj.toString();
runCount();
}
};
轉(zhuǎn)換后,第一行,handler名字這里報(bào)錯(cuò):

怎辦?看了alt+enter的提示,看不懂。
解決方案就是:
不用用handler做名字,換個(gè)hanlderOne啥的,handler這個(gè)名字好像已經(jīng)被占用了。
18.IDE 自帶的插件轉(zhuǎn)換 Java 代碼, 項(xiàng)目上線后后臺(tái)空指針Error增加(重要#############巨坑巨坑#################)
IDE 里面的插件 "Covert Java File To Kotlin File" 早已被大家熟知,要是不知道的小伙伴,趕緊寫個(gè) Java 文件,嘗試點(diǎn)擊 Android Studio 工具欄的 Code 下面的 "Convert Java File To Kotlin File"。
這樣的方式足夠地快,但卻會(huì)出現(xiàn)很多很多的 !!,這是由于 Kotlin 的 null safety 特性。這是 Kotlin 在 Android 開(kāi)發(fā)中的很牛逼的一大特性,想必不少小伙伴都被此 Android 的 NullPointException 困擾許久。我們直接轉(zhuǎn)換 Java 文件造成的各種 !! ,其實(shí)也就意味著你可能存在潛在的未處理的 KotlinNullPointException。
19. 資源id和object對(duì)象的變量名重名
if (FilmAllModel.INSTANCE.getTotal() == 1)
轉(zhuǎn)換為kotlin
if(total==1)
此處直接報(bào)錯(cuò),閱讀提示,發(fā)現(xiàn),我們的一個(gè)資源id也叫total,重名導(dǎo)致,報(bào)錯(cuò)。
20. 不變的枚舉
枚舉對(duì)開(kāi)發(fā)者非常友好。數(shù)量有限的元素,描述性的名字,因此大幅提高了代碼的可讀性。另外他還支持多態(tài)。由于這些原因枚舉在代碼中被廣泛使用?!宰髡?《Android 高性能編程》(西班牙)([恩里克·洛佩斯·馬尼亞斯](意)([迪戈·格蘭奇尼]
正如摘要所言,枚舉很好。但我不推薦枚舉,緣由有兩個(gè):
- 枚舉通常會(huì)占用兩倍于靜態(tài)常亮的內(nèi)存,在朱凱翻譯的android delveop官方性能優(yōu)化里已經(jīng)不推薦(Enums usually request twice as much memory as static constants)
- 枚舉在有幾個(gè)成員,就分別會(huì)被轉(zhuǎn)換為幾個(gè)對(duì)象, 并且分貝為他們的name 參數(shù)分配String 。。?!禔dnroid 高性能編程》也正因?yàn)槿绱耍院?jiǎn)化著稱的kotlin語(yǔ)言,少見(jiàn)的為enum添加一個(gè)class ,比java的創(chuàng)建還多一個(gè)關(guān)鍵字。就是因?yàn)樗举|(zhì)是一個(gè)類,而且還不是一個(gè)省心的class ,是class里面還有class。
在安卓高性能編程這本書(shū)里,作者推薦,用靜態(tài)常量代替枚舉類的成員,將枚舉類前面的enum,換成class,回歸一個(gè)正常的類。
說(shuō)了這么多有什么用呢? 因?yàn)閗otlin自動(dòng)轉(zhuǎn)換,枚舉類還是枚舉類,若要轉(zhuǎn)換的優(yōu)雅,還得自己操作。
怎么辦呢?
- 我們?cè)谵D(zhuǎn)換的時(shí)候也可以遵循這個(gè)步驟:
- 先將類轉(zhuǎn)換 2 . 再轉(zhuǎn)kotlin。
java代碼:
public enum EventType {
LOG_MINE,
UD_HEADER,
INVISIBLE_RED_DOT,
}
kotlin轉(zhuǎn)換:
object EventType {
const val LOG_MINE = 0
const val UD_HEADER = 1
const val INVISIBLE_RED_DOT = 2
}