Kotlin 與 Java基本語(yǔ)法對(duì)比
Kotlin 與 Java基本語(yǔ)法對(duì)比
Kotlin比Java更年輕,但它是一個(gè)非常有前途的編程語(yǔ)言,它的社區(qū)不斷增長(zhǎng)。 每個(gè)人都在談?wù)撍?,并說(shuō)它很酷。 但為什么這么特別?
我們準(zhǔn)備了一系列文章,分享我們?cè)贙otlin開發(fā)Android應(yīng)用程序的經(jīng)驗(yàn)。 我們將討論Kotlin與Java在語(yǔ)法,可用性,UI性能和異步性方面的區(qū)別,以便您可以決定哪種語(yǔ)言最適合您。
讓我們從一些基本的語(yǔ)法差異開始。 這是第一個(gè):
1. 使用Kotlin,你可以用更少的代碼做更多
Kotlin的一個(gè)主要優(yōu)點(diǎn)是它的簡(jiǎn)潔。 你用更少的代碼獲得更多的功能。 而你寫的代碼越少,你犯的錯(cuò)誤就越少。 這很簡(jiǎn)單。 讓
我們看看Kotlin的基礎(chǔ)知識(shí),從類開始。
public final class Person {
private String name;
private int age;
private float height;
public Person(String name, int age, float height) {
this.name = name;
this.age = age;
this.height = height;
}
public Person(String name, int age) {
this.name = name;
this.age = age;
this.height = 1.8f;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public float getHeight() {
return height;
}
public void setHeight(float height) {
this.height = height;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", height=" + height +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
if (age != person.age) return false;
if (Float.compare(person.height, height) != 0) return false;
return name != null ? name.equals(person.name) : person.name == null
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
result = 31 * result + (height != +0.0f ? Float.floatToIntBits(height) : 0);
return result;
}
}
上面是一個(gè)通常的Java類。 它做的不多。 它只包含一些數(shù)據(jù)。 但是,當(dāng)你意識(shí)到它給表帶來(lái)的不足時(shí),看看這段代碼有多大是很痛苦的。 為了鼓勵(lì)你,我們會(huì)給你一個(gè)等同的類寫在Kotlin。
data class Person(var name: String,
var age: Int,
var height: Float = 1.8f)
是的,你會(huì)為你的數(shù)據(jù)類自動(dòng)獲取需要的getters,setters,equals(),hashcode(),toString()和copy()函數(shù)! 當(dāng)然,你可以輕松地重寫這些函數(shù),但在大多數(shù)情況下,只需聲明類及其屬性就足夠了。
這正是我們的意思,當(dāng)我們說(shuō)Kotlin簡(jiǎn)潔。
2. 你可以避免 NullPointerException
現(xiàn)在我們想提醒你在許多編程語(yǔ)言中最大的痛苦 - 空指針異常。 我們幾乎不能想象自從托尼·霍爾在1965年發(fā)明它之后,有多少開發(fā)者遭受了空指針,同時(shí)試圖使事情更簡(jiǎn)單一些。
可悲的是,我們不能及時(shí)回來(lái),防止Tony犯這個(gè)錯(cuò)誤。 但是使用Kotlin,我們現(xiàn)在可以輕松地轉(zhuǎn)義NullPointerException。
val person: Person? = null ... person?.name = "John"
如果變量是可空的,編譯器將不允許你訪問(wèn)它沒(méi)有適當(dāng)?shù)臋z查。 Kotlin強(qiáng)迫你使用? 運(yùn)算符。 這可以防止應(yīng)用程序自動(dòng)崩潰。
它如何在引擎蓋下工作? 讓我們回顧一下生成的字節(jié)碼。
L2 LINENUMBER 18 L2 ALOAD 3 DUP IFNULL L3 LDC "John" INVOKEVIRTUAL igalata/com/kotlinexample/Person.setName (Ljava/lang/String;)V GOTO L4 L3 POP
正如你所看到的,我們?cè)谶@里有相同的空檢查。 JetBrains的開發(fā)人員(創(chuàng)建Kotlin)知道每次檢查我們的變量是避免NullPointerException的唯一方法。 但他們也知道Android開發(fā)人員不想在他們的項(xiàng)目中處理NullPointerException。 他們可能想:“為什么不自動(dòng)生成這個(gè)檢查如果變量是可空的?
JetBrains的開發(fā)人員只是這樣,讓我們的生活更容易了!
3. 你可以擺脫util類
讓我們來(lái)討論一下有關(guān)使用util類的丑陋事情。 你有沒(méi)有一個(gè)項(xiàng)目沒(méi)有他們? 我們幾乎不記得這一切。 Kotlin有一個(gè)聰明的解決方案 - 擴(kuò)展功能 - 幫助你擺脫所有的util類一勞永逸。
擴(kuò)展函數(shù)幾乎是一個(gè)通常的Kotlin函數(shù)。 但是當(dāng)你聲明它,你需要指定的實(shí)例將具有擴(kuò)展功能的類。
fun Context.toast(text: String) = Toast.makeText(this, text, Toast.LENGTH_SHORT).show()
注意'this',我們作為參數(shù)傳遞給makeText()方法? 它不是類的一個(gè)實(shí)例,我們聲明這個(gè)函數(shù),而是一個(gè)Context實(shí)例。 現(xiàn)在你可以直接從你的Activity或任何其他Context實(shí)例調(diào)用這個(gè)函數(shù)。 例如:
toast("Hi")
你應(yīng)該記住,擴(kuò)展函數(shù)不以任何方式修改它擴(kuò)展的類。 那么它如何工作而不改變?cè)瓉?lái)的類? 讓我們?cè)俅慰吹阶止?jié)碼。
public final toast(Landroid/content/Context;Ljava/lang/String;)V @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0 @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 1 L0 ALOAD 1 LDC "$receiver" INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull (Ljava/lang/Object;Ljava/lang/String;)V ALOAD 2 LDC "text" INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull (Ljava/lang/Object;Ljava/lang/String;)V L1 LINENUMBER 31 L1 ALOAD 1 ALOAD 2 CHECKCAST java/lang/CharSequence ICONST_0 INVOKESTATIC android/widget/Toast.makeText (Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast; INVOKEVIRTUAL android/widget/Toast.show ()V L2 LINENUMBER 32 L2 RETURN L3 LOCALVARIABLE this Ligalata/com/kotlinexample/MainActivity; L0 L3 0 LOCALVARIABLE $receiver Landroid/content/Context; L0 L3 1 LOCALVARIABLE text Ljava/lang/String; L0 L3 2 MAXSTACK = 3 MAXLOCALS = 3
哈! 您的函數(shù)隱式接收它作為第一個(gè)參數(shù)擴(kuò)展的類的實(shí)例。 因此,在字節(jié)碼中,對(duì)函數(shù)體中“this”的任何訪問(wèn)都將替換為對(duì)第一個(gè)參數(shù)的訪問(wèn)。 沒(méi)有魔法真的。 您可以在項(xiàng)目的任何位置使用此函數(shù)。
時(shí)間刪除你的util包!
4. 你可以忘記視圖綁定
你還記得findViewById()method()嗎? 我們相信你不喜歡它。 我們也不是。 此外,我們不想為我們需要訪問(wèn)的每個(gè)視圖聲明變量和Butterknife注釋。
你可以忘記與Kotlin Android Extensions的視圖綁定。 不再需要?jiǎng)?chuàng)建變量和綁定視圖。 您可以使用在xml布局中聲明的標(biāo)識(shí)符直接訪問(wèn)您的視圖。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
final TextView text = (TextView) findViewById(R.id.text);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
text.setText("You've clicked a button");
}
});
}
}
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {
super.onCreate(savedInstanceState, persistentState)
setContentView(R.layout.activity_main)
button.setOnClickListener { text.text = "You've clicked a button" }
}
}
這太簡(jiǎn)單了,不是嗎?
基本上,findViewById()方法仍在使用中。 但是沒(méi)有必要自己寫。 Kotlin會(huì)為你做。
當(dāng)您使用Android擴(kuò)展時(shí),findCachedViewById()函數(shù)和HashMap實(shí)例將會(huì)自動(dòng)生成。 每次通過(guò)其標(biāo)識(shí)符訪問(wèn)您的視圖將被一個(gè)新的函數(shù)調(diào)用替換。 如果是第一次訪問(wèn)視圖,此函數(shù)將調(diào)用通常的findViewById()函數(shù),并將接收的視圖添加到HashMap中,以便在下次訪問(wèn)視圖時(shí)從中檢索視圖。
5. 你可以更容易地使用集合
讓我們談?wù)凨otlin的集合。 因?yàn)槲覀兘?jīng)常需要使用數(shù)據(jù)模型集合執(zhí)行困難的操作。 例如,我們可能有一個(gè)學(xué)生名單,我們需要從中檢索三個(gè)A級(jí)成績(jī)的學(xué)生和兩個(gè)B成績(jī)的學(xué)生。
看看Kotlin的解決方案:
var students = listOf(Student("John", 0), Student("Julia", 2), Student("Matt", 1),
Student("Katie", 0), Student("Dan", 0))
var firstList = students.filter { it.mark == 0 }.take(3)
var secondList = students.filter { it.mark == 1 }.take(2)
下面是我們?nèi)绾谓鉀QJava中的同樣的問(wèn)題:
ArrayList<Student> students = new ArrayList<Student>() {{
add(new Student("John", 0));
add(new Student("Julia", 2));
add(new Student("Matt", 1));
add(new Student("Katie", 0));
add(new Student("Dan", 0));
}};
ArrayList<Student> firstList = new ArrayList<>();
ArrayList<Student> secondList = new ArrayList<>();
for (Student student: students) {
boolean isFirstFilled = firstList.size() >= 3;
boolean isSecondFilled = secondList.size() >= 2;
if (isFirstFilled && isSecondFilled) break;
int mark = student.getMark();
if (mark == 0 && !isFirstFilled) {
firstList.add(student);
} else if (mark == 1 && !isSecondFilled) {
secondList.add(student);
}
}
這只是一個(gè)小例子,說(shuō)明如何在Kotlin和Java中使用集合,但你可以看到差別! 你能想象如果我們處理一個(gè)大項(xiàng)目的集合,Kotlin會(huì)有什么區(qū)別嗎?
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
相關(guān)文章
Java?Chassis3熔斷機(jī)制的改進(jìn)路程技術(shù)解密
這篇文章主要介紹了Java?Chassis?3技術(shù)解密之熔斷機(jī)制的改進(jìn)路程實(shí)例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01
Eureka注冊(cè)不上或注冊(cè)后IP不對(duì)(多網(wǎng)卡的坑及解決)
這篇文章主要介紹了Eureka注冊(cè)不上或注冊(cè)后IP不對(duì)(多網(wǎng)卡的坑及解決),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11
Spring?MVC請(qǐng)求轉(zhuǎn)發(fā)與請(qǐng)求重定向的示例詳解
轉(zhuǎn)發(fā)指服務(wù)器接收請(qǐng)求后,從一個(gè)資源跳轉(zhuǎn)到另一個(gè)資源中,請(qǐng)求轉(zhuǎn)發(fā)是一次請(qǐng)求,不會(huì)改變?yōu)g覽器的請(qǐng)求地址,這篇文章主要介紹了Spring?MVC請(qǐng)求轉(zhuǎn)發(fā)與請(qǐng)求重定向的相關(guān)知識(shí),需要的朋友可以參考下2023-09-09
Java Hibernate中使用HQL語(yǔ)句進(jìn)行數(shù)據(jù)庫(kù)查詢的要點(diǎn)解析
HQL是Hibernate框架中提供的關(guān)系型數(shù)據(jù)庫(kù)操作腳本,當(dāng)然我們也可以使用原生的SQL語(yǔ)句,這里我們來(lái)看一下在Java Hibernate中使用HQL語(yǔ)句進(jìn)行數(shù)據(jù)庫(kù)查詢的要點(diǎn)解析:2016-06-06
RestTemplate如何通過(guò)HTTP?Basic?Auth認(rèn)證示例說(shuō)明
這篇文章主要為大家介紹了RestTemplate如何通過(guò)HTTP?Basic?Auth認(rèn)證的示例說(shuō)明,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-03-03
Java中關(guān)于子類覆蓋父類的拋出異常問(wèn)題
今天小編就為大家分享一篇關(guān)于Java中關(guān)于子類覆蓋父類的拋出異常問(wèn)題,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-04-04
簡(jiǎn)單解析execute和submit有什么區(qū)別
這篇文章主要介紹了簡(jiǎn)單解析execute和submit有什么區(qū)別,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-11-11

