Kotlin與Java互調(diào)原理項(xiàng)目實(shí)戰(zhàn)

數(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,怎么辦?
正確的做法:

  1. 注釋和單例相關(guān)的方法:

    private static class SingletonHolder {
        private static final DataBeanModel INSTANCE = new DataBeanModel();
    }

    private DataBeanModel() {
    }

    public static final DataBeanModel getInstance() {
        return SingletonHolder.INSTANCE;
    }

  1. 按下ctrl shift alt k 轉(zhuǎn)換成kotlin,將類關(guān)鍵字class 替換為Object
  2. 刪除注釋部分

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)
    }
}

  1. 調(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文件:重要#############巨坑巨坑#################
image

之前我們項(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ò):

image

怎辦?看了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è):

  1. 枚舉通常會(huì)占用兩倍于靜態(tài)常亮的內(nèi)存,在朱凱翻譯的android delveop官方性能優(yōu)化里已經(jīng)不推薦(Enums usually request twice as much memory as static constants)
  1. 枚舉在有幾個(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è)步驟:
  1. 先將類轉(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
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容