一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Android - Android開發(fā)筆記之:用Enum(枚舉類型)取代整數(shù)集的應(yīng)用詳解

Android開發(fā)筆記之:用Enum(枚舉類型)取代整數(shù)集的應(yīng)用詳解

2021-01-17 16:59Android開發(fā)網(wǎng) Android

本篇文章是對(duì)Android中用Enum(枚舉類型)取代整數(shù)集的應(yīng)用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下

在android的api中可以發(fā)現(xiàn)有很多用整數(shù)集來作為參數(shù)的地方,先來看一下實(shí)例。
linearlayout是大家所熟知的一個(gè)ui基本元素,它里面有一個(gè)方向的屬性,可以通過以下方法來設(shè)置:

復(fù)制代碼 代碼如下:


linearlayout.setorientation(int);


使用的時(shí)候,通常都是這樣:

復(fù)制代碼 代碼如下:


linearlayout.setorientation(linearlayout.horizontal);
linearlayout.setorientation(linearlayout.vertical);


但也可以這樣使用:

復(fù)制代碼 代碼如下:


linearlayout.setorientation(0); // linearlayout.horizontal = 0
linearlayout.setorientation(1); // linearlayout.vertical = 0x01


甚至可以這樣:

復(fù)制代碼 代碼如下:


linearlayout.setorientation(integer.max_value);
linearlayout.setorientation(integer.min_value);
linearlayout.setorientation(2012);


因?yàn)榉椒╯etorientation接收的參數(shù)是一個(gè)整數(shù),所以你可以傳任意合法的整數(shù)---至少這在編譯時(shí)不會(huì)有任何問題。它只會(huì)在運(yùn)行時(shí)可能引發(fā)問題,但如你所知,開發(fā)者只關(guān)注程序能否編譯成功,至于運(yùn)行時(shí),那是用戶關(guān)心的事兒,因?yàn)殚_發(fā)者不一定使用他們所開發(fā)出的程序。

除了這個(gè)例子,在android的api中到處可以看到這種api,比如設(shè)置view的可見性,設(shè)置wifi狀態(tài)等等。都是定義了整數(shù)集,然后用整數(shù)來做為參數(shù),并寄希望開發(fā)者能傳遞整數(shù)集中定義的常量來作為參數(shù)。但如你所知,并不是每個(gè)人都那么的守規(guī)矩,如果每個(gè)人都能遵守規(guī)則,這個(gè)世界就真的和諧了,蛋扯遠(yuǎn)了。
因?yàn)殚_發(fā)者通常只能關(guān)注編譯,所以如果能把這個(gè)規(guī)則應(yīng)用在編譯時(shí),那么就會(huì)大大減少出錯(cuò)的可能。有興趣的朋友可以去試試看,給這些接收整數(shù)參數(shù)的方法傳一些“平常”的數(shù)值,比如2012,integer.max_value,integer.min_value等等,看會(huì)出現(xiàn)什么狀況。
另外,如果開發(fā)者傳遞與常量定義一致的整數(shù)值,雖然編譯運(yùn)行都不會(huì)有錯(cuò),但代碼的可讀性會(huì)大大的降低,比如:

復(fù)制代碼 代碼如下:


linearlayout.setorientation(0);
linearlayout.setorientation(1);


這完全沒有錯(cuò),但是代碼的閱讀者和維護(hù)者通常都會(huì)蛋疼的。
當(dāng)然,android自身還是有保護(hù)措施的,如果對(duì)api傳遞不合法參數(shù),不會(huì)造成其他影響,只是設(shè)置不能生效,但api會(huì)使用默認(rèn)值,因?yàn)閷?duì)于每個(gè)內(nèi)置參數(shù),都有相應(yīng)的默認(rèn)值。如linearlayout的orientation,默認(rèn)值就是linearlayout.horizontal,所以如果對(duì)setorientation()傳入非法值,linearlayout會(huì)保持水平排列,無其他影響。后面有個(gè)對(duì)linearlayout的orientation做的試驗(yàn)。
另外,如果在layout xml文件中設(shè)置這些屬性就不會(huì)有些問題,如:

復(fù)制代碼 代碼如下:


<linearlayout
android:orientation="vertical"
android:gravity="center">


因?yàn)閤ml布局會(huì)在編譯時(shí)被處理,如果有非法的值,會(huì)有編譯錯(cuò)誤的。我想這也就是android特別鼓勵(lì)開發(fā)者用xml來制作所有的布局的一個(gè)原因吧。實(shí)例,三個(gè)沒有設(shè)置指向的線性布局,默認(rèn)是水平放置,在代碼中設(shè)置了幾個(gè)離譜的值,發(fā)現(xiàn)它們還是水平的,也就是說設(shè)置離譜的值不會(huì)出錯(cuò),但也不起作用:運(yùn)行結(jié)果如下:

Android開發(fā)筆記之:用Enum(枚舉類型)取代整數(shù)集的應(yīng)用詳解
代碼如下:

復(fù)制代碼 代碼如下:


<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center"
    >
    <linearlayout
        android:id="@+id/linearlayout_test_1"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content">

   <textview
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:textcolor="#ff00ff00"
     android:background="#aa331155"
     android:layout_weight="1"
     android:textsize="18sp"
     android:text="microsoft"
        />
   <textview
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textcolor="#ffff0000"
        android:background="#aa117711"
        android:layout_weight="1"
        android:textsize="18sp"
        android:text="apple"
        />
   <textview
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textcolor="#ff0000ff"
        android:background="#aa774411"
        android:layout_weight="1"
        android:textsize="18sp"
        android:text="google"
        />
    </linearlayout>
    <linearlayout
        android:id="@+id/linearlayout_test_2"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">

      <textview
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:textcolor="#ff00ff00"
           android:background="#aa331155"
           android:layout_weight="1"
           android:textsize="18sp"
           android:text="microsoft"
           />
      <textview
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:textcolor="#ffff0000"
           android:background="#aa117711"
           android:layout_weight="1"
           android:textsize="18sp"
           android:text="apple"
           />
      <textview
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:textcolor="#ff0000ff"
           android:background="#aa774411"
           android:layout_weight="1"
           android:textsize="18sp"
           android:text="google"
           />
    </linearlayout>
    <linearlayout
        android:id="@+id/linearlayout_test_3"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">

      <textview
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:textcolor="#ff00ff00"
           android:background="#aa331155"
           android:layout_weight="1"
           android:textsize="18sp"
           android:text="microsoft"
           />
      <textview
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:textcolor="#ffff0000"
           android:background="#aa117711"
           android:layout_weight="1"
           android:textsize="18sp"
           android:text="apple"
           />
      <textview
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:textcolor="#ff0000ff"
           android:background="#aa774411"
           android:layout_weight="1"
           android:textsize="18sp"
           android:text="google"
           />
    </linearlayout>
</linearlayout>


和:

復(fù)制代碼 代碼如下:


package com.android.explorer;
import android.app.activity;
import android.os.bundle;
import android.widget.linearlayout;
public class linearlayouttest extends activity {
    @override
    public void oncreate(bundle savedinstancestate) {
        super.oncreate(savedinstancestate);
        setcontentview(r.layout.linearlayout_test);
        linearlayout one = (linearlayout) findviewbyid(r.id.linearlayout_test_1);
        one.setorientation(2012);
        linearlayout two = (linearlayout) findviewbyid(r.id.linearlayout_test_2);
        two.setorientation(integer.max_value);
        linearlayout three = (linearlayout) findviewbyid(r.id.linearlayout_test_3);
        three.setorientation(integer.min_value);
    }
}


用enum代替整數(shù)集
其實(shí)很簡(jiǎn)單,用enum(枚舉)就可以很方便的解決這個(gè)問題,使用起來也不比定義整數(shù)集繁瑣,同樣的可讀。另外的優(yōu)點(diǎn)就是,它的封裝更好,最重要的是它會(huì)在編譯時(shí)被檢查。因?yàn)閖ava是一種strong type,也就是說在編譯時(shí),編譯器會(huì)對(duì)所有原型類型和參數(shù)類型進(jìn)行檢查,如果類型不對(duì),并且沒有強(qiáng)制轉(zhuǎn)型的,就會(huì)報(bào)出編譯錯(cuò)誤,當(dāng)然編譯器所支持的自動(dòng)轉(zhuǎn)型除外。比如一個(gè)需要int,而傳的參數(shù)是long,雖然都差不多,沒有溢出等,但還是會(huì)有編譯錯(cuò)誤。
所以,如果linearlayout使用enum,就像這樣定義:

復(fù)制代碼 代碼如下:


public class linearlayout extends viewgroup {
    private orientation morientation;

    public enum orientation {
        horizontal, vertical
    };

    public void setorientation(orientation dir) {
        morientation = dir;
    }
}


然后這樣使用:

復(fù)制代碼 代碼如下:


import android.widget.linearlayout;
linearlayout.setorientation(orientation.horizontal);
linearlayout.setorientation(orientation.vertical);


那么,開發(fā)者就不會(huì)用錯(cuò)了,因?yàn)槭紫龋吹絪etorientation所需要的參數(shù)是一個(gè)orientation的枚舉類型,就會(huì)自然的傳送orientation中定義的類型;另外,如果傳其他的值,比如0或者1,編譯器也不會(huì)答應(yīng)的。

可悲的是android中幾乎所有的api都是以整數(shù)集的方式來定義的,所以就要時(shí)刻提醒自己和組里的人,一定要傳所定義的整數(shù)集中的常量。
那么我們能做的,除了要傳整數(shù)集中定義的常量,對(duì)于那些以整數(shù)集方式定義的api,以外。更重要的是當(dāng)自己定義接口的時(shí)候,盡量用enum而不要使用整數(shù)集。
還有一點(diǎn)需要注意的是,對(duì)于某些弱類型語言,也就是說在編譯時(shí)不會(huì)對(duì)類型做特別細(xì)致的檢查,比如c++,c等,那么即使使用了enum,也不一定安全,因?yàn)閷?duì)于c++和c來講enum中的常量與整數(shù)常量完全一樣,連編譯器都分不清。所以,對(duì)于這類語言,只能寄希望于開發(fā)者了。
后記:
寫完這篇,讓我想起了另外一些與參數(shù)定義相關(guān)的問題,比如布爾型參數(shù)也不是一個(gè)很好的設(shè)計(jì),因?yàn)槭褂谜吆茈y到底應(yīng)該傳true還是傳false,特別是當(dāng)方法名字不能體現(xiàn)boolean參數(shù)作用時(shí)和文檔不夠清楚的時(shí)候。如果只有一個(gè)參數(shù)還好,根據(jù)方法名字和常識(shí)都能知道,比如:

復(fù)制代碼 代碼如下:


button.setenabled(true); // enable the button
button.setenabled(false); // disable the button


但對(duì)于某些情況,當(dāng)方法的名字不能體現(xiàn)boolean參數(shù)的作用時(shí),或是多于一個(gè)參數(shù)時(shí),而方法的主要目的又不能體現(xiàn)boolean參數(shù)的作用時(shí),就很不清楚,比如:

復(fù)制代碼 代碼如下:


// com/android/mms/data/contactlist.java
public string[] getnumbers(boolean);


您能猜出來這個(gè)boolean變量是決定是否要為彩信對(duì)聯(lián)系人做特殊的處理嗎?您在使用這個(gè)api的時(shí)候能很快知道該傳true還是該傳false嗎?當(dāng)讀到這些語句的時(shí)候:

復(fù)制代碼 代碼如下:


string[] mms = getnumbers(true);
string[] sms = getnumbers(false);


您能知道true和false的含義與作用嗎?至少我看到這樣的代碼時(shí),如果不去跟蹤它的實(shí)現(xiàn),是猜不出來的。
但現(xiàn)實(shí)的問題是,api通常又需要從調(diào)用者那里得到做還是不做的決定。一個(gè)可行的途徑是用方法來封裝和隱藏,比如:

復(fù)制代碼 代碼如下:


button.setenabled(true); // enable the button
button.setenabled(false); // disable the button


可以改成:

復(fù)制代碼 代碼如下:


button.enable();
button.disable();


這是簡(jiǎn)單的情況,對(duì)于稍復(fù)雜的情況,比如后一個(gè)例子,可以添加另外的接口,而不是用重載方法,但內(nèi)部的實(shí)現(xiàn),可能還是需要重載,但是這就把問題縮小了,起碼對(duì)使用者來說是隱藏的:

復(fù)制代碼 代碼如下:


// com/android/mms/data/contactlist.java
public string[] getnumbersforsms();
public string[] getnumbersformms();


這樣一來,對(duì)外來講就是良好的封裝。內(nèi)部實(shí)現(xiàn)可能還是需要一個(gè)類似這樣的私有方法:

復(fù)制代碼 代碼如下:


// com/android/mms/data/contactlist.java
public string[] getnumbersforsms() {
   return getnumbers(false);
}
public string[] getnumbersformms() {
   return getnumbers(true);
}
private string[] getnumbers(boolean) {
   // implementation
}


但至少把問題縮小化了,也可以加上注釋來說明。就不必導(dǎo)致使用者來猜方法的用法和含義了。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 成人免费淫片95视频观看网站 | 亚洲黄网站wwwwww | 日本一卡二卡3卡四卡网站精品 | www.日本免费 | 国产成人精品s8sp视频 | 国产精品久久久久久搜索 | 艹b小说| 欧美jjvideo| 欧美成人禁片在线观看俄罗斯 | 国产99页 | 四虎国产精品免费久久麻豆 | 国产午夜精品一区二区三区不卡 | 免费看片黄色 | 欧美a级v片在线观看一区 | 国产精品吹潮香蕉在线观看 | 国产精品制服丝袜白丝www | freesex性欧美炮机喷潮 | 亚洲免费二区 | 免费草比视频 | 99精品国产自产在线观看 | 高清一级做a爱免费视 | 精品视频网站 | 男人的天堂欧美 | 日本人妖在线 | chinesespank打屁股| 女人c交zzzooo在线观看 | 国产99在线观看 | 欧洲vodafonewi精品 | 性欧美4khdxxxx| 手机看片国产自拍 | 99色在线视频 | 精品国产乱码久久久久久免费流畅 | 美女脱衣有肉 | 太紧太深了受不了黑人 | 欧美专区在线播放 | 99精品国产自产在线观看 | 精品无人区乱码1区2区3区在线 | zoz.zzz色 | 亚洲人成激情在线播放 | 4455在线| 我的奶头被客人吸的又肿又红 |