1. 程式人生 > >在case標籤中使用非靜態欄位

在case標籤中使用非靜態欄位

譯文

前言

找到這篇文章之前,主要是因為在以前一個公司專案中,實現點選事件介面的時候有這種寫法。

public void onClick(View view){
  switch(view.getId()){
      case R.id.xx1:
      break;
      case R.id.xx2:
      break;
      case R.id.xx3:
      break;

  }
}

然後我們領導說這種寫法存在這問題,新api下(具體說的那個api我給忘了)可能會出現id重複的情況,不嚴謹。然後使用這種寫法:

public void
onClick(View view){ if(view.getId() == R.id.xx1){ }else if(view.getId == R.id.xx2){ }else if(view.getId == R.id.xx3){ } }

當時我是一臉懵逼,不置可否。回頭就查了一下資料。找到這篇文章。

正文

在規則的android專案中, R檔案裡面生命的資源常量一般像

public static final int main=0x7f030004;

然而,截止 ADT 14,在library專案中,這些常量會被宣告成:

public static int
main=0x7f030004;

換言之,library專案中的資源常量不在是final的。原因其實很簡單,當多個library專案結合的時候,這個值無法保證唯一性。
在ADT 14之前, 所有的欄位是final的, 因為這個原因, 所有的library必須擁有資源而且需要將與main project關聯的java程式碼重新編譯。這樣會影響效能,導致build變慢。這樣做也阻止了不含source code 的library project的分發,限制了library專案的使用範圍。

由於欄位不再是final的 所以也就意味著library jars可以一次編譯,直接在別的專案中重用。而且編譯速度變快了。

然而,像下面這種資原始碼就無法在library專案編譯了。


int id = view.getId();
switch (id) {
    case R.id.button1:
        action1();
        break;
    case R.id.button2:
        action2();
        break;
    case R.id.button3:
        action3();
        break;
}

這是因為 switch語句要求case 標籤,就像 R.id.button1,在編譯的時候必須是常量。
(這個值會直接複製到.class檔案中)。
為了解決這個問題,替換switch語句為if-else語句。幸好,這個操作在Eclipse是非常簡單的。
僅僅是將游標放在switch關鍵詞上,然後點選Ctrl-1(或者Cmd-1 on mac)。
使用之後將會將switch程式碼轉換為如下:

int id = view.getId();
if (id == R.id.button1) {
    action1();
} else if (id == R.id.button2) {
    action2();
} else if (id == R.id.button3) {
    action3();
}

這是一般的UI程式碼,而且效能損失是微不足道的。
我們有一個探測器可以找到這種錯誤,而且會提供一個簡單的介紹。
地址

總結
所以這麼看來,因為library專案R檔案中id不是final的,switch 語句需要將case 標籤copy到.class 檔案中。所以在library專案中switch語句中case標籤不能為R.id.xxx。但是在非library中R.id.xxx 是final的,所以switch照用。

ps:
如果你的switch 語句像這樣寫:

switch (view.getId()) {

那麼最終你將會有一個無效的if-else 鏈。而且每一個if檢查都會請求呼叫view.getId()方法。所以要把view.getId()。方法放到前面來。(我擦我一直這麼寫的)

相關推薦

case標籤中使用非靜態

譯文 前言 找到這篇文章之前,主要是因為在以前一個公司專案中,實現點選事件介面的時候有這種寫法。 public void onClick(View view){ switch(view.getId()){ case R.id.xx1

使用類的靜態和建構函式,可以跟蹤某個類所建立物件的個數

  package TongJi; public class Duixiang { private static int n; public Duixiang() { n++; } public static int g

使用類的靜態和建構函式,可以跟蹤某個類所建立物件的個數。請寫一個類,在任何時候都可以向它查詢“你已經建立了多少個物件

package demo; public class Tongji { private static int n; public Tongji() { n++;//次new一個物件的時候都可以給n加1 } public static int ge

使用類的靜態和建構函式,跟蹤某個類所建立物件的個數

建立一個靜態變數,每生成一個物件,使該變數加一 package trackobjectnum; public class ObjectNum { private static int n = 0; public ObjectNum() { n = n + 1;

類的靜態和建構函式

package jiecheng; public class sum { public static int a=0; int c; public sum(int cc) { c=cc; a++; } public int get() { return a; }}

C# 類中的靜態始終繼承自基類

我們試想一下現在有一個類Parent,它有一個static的int型別欄位number,然後如果類Parent有三個子類Child01、Child02和Child03,那麼改變Parent.number的值的話,Child01.number、Child02.number和Child03.number的值也會被

SQL之CASE表示式總結之二:利用CASE語句來更新的值

可以在UPDATE語句中使用CASE表示式來方便的更新欄位的值 例項:有如下工資表: 要求: (1)對目前工資為30000元以上的員工,降薪10% (2)對目前工資為25000元以上且不滿28000元的員工,加薪20% (3)上述條件以外的情形的員工,保持不變 [分析]:按照常規思路,直接對資

Android-NDK學習記錄4-C呼叫Java靜態方法修改靜態

一. jni互動相關-方法簽名 方法簽名在jni的使用中經常都會用到,在java中會有過載,那麼定位到一個方法的方式:類+方法名稱+方法簽名,那麼我們先學習下簽名規則: 基本型別簽名: 咱們基本型別有各自的簽名,如下表 型別名

C#變數初始化問題:初始值無法引用非靜態、方法或屬性

問題:欄位初始值設定項無法引用非靜態欄位、方法或屬性的問題 下面程式碼出錯的原因,在類中定義的欄位為什麼不能用? (1) public string text = test(); //提示 欄位或屬性的問題欄位初始值設定項無法引用非靜態欄位、方法 protected vo

子類引用父類的靜態,不會導致子類初始化

先看程式碼 // 父類 public class SuperClass { static { System.out.println("SuperClass Init!"); } public static int valu

Java物件和例項的關係、Java資料封裝、Java繼承和多型、Java抽象類和介面、Java靜態和方法、Java包和作用域、Java的classpath和jar、Java核心類

Java物件和例項的關係: 面向物件程式設計(Object-Oriented Programming),是對現實世界建立計算機模型的一種方法。 class是物件的模板,它定義瞭如何建立例項,class的名字就是資料型別。一個class裡可以有多個欄位(field),欄位用

Typescript 靜態(static)的宣告

ts中定義靜態變數,加 public static, 和C#中類似。  定義: export class GlobalService { public static url: string = "http://localhost:4200/webapp"; } 引用:

Java基礎,外部類能夠訪問內部類的私有靜態

外部類能夠訪問內部類的私有靜態欄位。 public class Singleton { private Singleton() { } public static Singleton getInstance() { retur

Spring MVC 屬性檔案讀取注入到靜態

在專案中,有些引數需要配置到屬性檔案xxx.properties中,這樣做是為了維護方便,如果需要變動只需修改屬性檔案,不需要重新編譯專案就可以了,非常方便。 而為了使用起來方便,可以通過將屬性值注入到類的靜態欄位中(static),這樣就可以用classNa

Oracle case when 實現資料資料的判斷過濾

需求 現在有一份管線資料,表中含有欄位buildTime說明了管線的建設日期,我們需要按時間段統計管線的資料 這是,我們需要對管線表中建設日期所對應的欄位進行分類 實現如下: 實現 對現有的資料進行分類判斷過濾,使用到了 case when ca

初始值無法引用非靜態、方法

欄位初始值設定項無法引用非靜態欄位、方法或屬性 如 int i= 此值是用來初始化欄位i的 不能使用非靜態欄位 [c-sharp] view plaincopyprint? //錯誤 int j=5;  int i=j ;  //此行報出此編譯錯誤 正確  int i=5 //或 static

Python類中的“靜態”“動態”“靜態方法”“動態方法”

首先,要知道Python類中兩個概念:欄位和方法 “欄位”和“方法”都有“動態”和“靜態”之分,即: 欄位 - 靜態欄位 - 動態欄位方法 - 靜態方法 - 動態方法 以下事例標明瞭:“靜態欄位”,“動態欄位”以及“動態方法”是什麼樣子的,因為顯而易見,就不用語言進行過多

android build類分析 hook靜態

一、緣由: 使用xposed hook build類下 DEVICE MODEL VERSION MANUFACTURER等靜態欄位 使用XposedHelpers.setStaticObjectField() hook 失敗! XposedHelp

深入理解 c# 第三章 證明不同的封閉類具有不同的靜態

class StaticFieldPerClosedType { class TypeWithField<T> { public static string field;