Kotlin VS Java:基本語法差別

  Kotlin比Java更年輕,但它是一個很是有前途的編程語言,它的社區不斷增加。 每一個人都在談論它,並說它很酷。 但爲何這麼特別?
  
  咱們準備了一系列文章,分享咱們在Kotlin開發Android應用程序的經驗。 咱們將討論Kotlin與Java在語法,可用性,UI性能和異步性方面的區別,以便您能夠決定哪一種語言最適合您。
  
  讓咱們從一些基本的語法差別開始。 這是第一個:
  
  1. 使用Kotlin,你能夠用更少的代碼作更多
  
  Kotlin的一個主要優勢是它的簡潔。 你用更少的代碼得到更多的功能。 而你寫的代碼越少,你犯的錯誤就越少。 這很簡單。 讓咱們看看Kotlin的基礎知識,從類開始。
  
  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(027yeshenghuowang.com/) {
  
  int result = name != null ? name.hashCode() : 0;
  
  result = 31 * result + age;
  
  result = 31 * result + (height != +0.0f ? Float.floatToIntBits(height) : 0);
  
  return result;
  
  }
  
  }
  
  上面是一個一般的Java類。 它作的很少。 它只包含一些數據。 可是,當你意識到它給錶帶來的不足時,看看這段代碼有多大是很痛苦的。 爲了鼓勵你,咱們會給你一個等同的類寫在Kotlin。
  
  data class Person(var name: String,
  
  var age: Int,
  
  var height: Float = 1.8f)
  
  是的,你會爲你的數據類自動獲取須要的getters,setters,equals(www.xyseo.net),hashcode(),toString()和copy()函數! 固然,你能夠輕鬆地重寫這些函數,但在大多數狀況下,只需聲明類及其屬性就足夠了。
  
  這正是咱們的意思,當咱們說Kotlin簡潔。
  
  2. 你能夠避免 NullPointerException
  
  如今咱們想提醒你在許多編程語言中最大的痛苦 - 空指針異常。 咱們幾乎不能想象自從託尼·霍爾在1965年發明它以後,有多少開發者遭受了空指針,同時試圖使事情更簡單一些。
  
  可悲的是,咱們不能及時回來,防止Tony犯這個錯誤。 可是使用Kotlin,咱們如今能夠輕鬆地轉義NullPointerException。
  
  val person: Person? = null
  
  ...
  
  person?.name = "John"
  
  若是變量是可空的,編譯器將不容許你訪問它沒有適當的檢查。 Kotlin強迫你使用? 運算符。 這能夠防止應用程序自動崩潰。
  
  它如何在引擎蓋下工做? 讓咱們回顧一下生成的字節碼。
  
  L2
  
  LINENUMBER 18 L2
  
  ALOAD 3
  
  DUP
  
  IFNULL L3
  
  LDC "John"
  
  INVOKEVIRTUAL igalata/com/kotlinexample/Person.setName (Ljava/lang/www.yigouyule2.cn/ String;)V
  
  GOTO L4
  
  L3
  
  POP
  
  正如你所看到的,咱們在這裏有相同的空檢查。 JetBrains的開發人員(建立Kotlin)知道每次檢查咱們的變量是避免NullPointerException的惟一方法。 但他們也知道Android開發人員不想在他們的項目中處理NullPointerException。 他們可能想:「爲何不自動生成這個檢查若是變量是可空的?
  
  JetBrains的開發人員只是這樣,讓咱們的生活更容易了!
  
  3. 你能夠擺脫util類
  
  讓咱們來討論一下有關使用util類的醜陋事情。 你有沒有一個項目沒有他們? 咱們幾乎不記得這一切。 Kotlin有一個聰明的解決方案 - 擴展功能 - 幫助你擺脫全部的util類一勞永逸。
  
  擴展函數幾乎是一個一般的Kotlin函數。 可是當你聲明它,你須要指定的實例將具備擴展功能的類。
  
  fun Context.toast(text: String) = Toast.makeText(this, text, Toast.LENGTH_SHORT).show()
  
  注意'this',咱們做爲參數傳遞給makeText()方法? 它不是類的一個實例,咱們聲明這個函數,而是一個Context實例。 如今你能夠直接從你的Activity或任何其餘Context實例調用這個函數。 例如:
  
  toast("Hi")
  
  你應該記住,擴展函數不以任何方式修改它擴展的類。 那麼它如何工做而不改變原來的類? 讓咱們再次看到字節碼。
  
  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 (www.22yigouyule.cn/)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
  
  哈! 您的函數隱式接收它做爲第一個參數擴展的類的實例。 所以,在字節碼中,對函數體中「this」的任何訪問都將替換爲對第一個參數的訪問。 沒有魔法真的。 您能夠在項目的任何位置使用此函數。
  
  時間刪除你的util包!
  
  4. 你能夠忘記視圖綁定
  
  你還記得findViewById()method()嗎? 咱們相信你不喜歡它。 咱們也不是。 此外,咱們不想爲咱們須要訪問的每一個視圖聲明變量和Butterknife註釋。
  
  你能夠忘記與Kotlin Android Extensions的視圖綁定。 再也不須要建立變量和綁定視圖。 您可使用在xml佈局中聲明的標識符直接訪問您的視圖。
  
  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" }
  
  }
  
  }
  
  這太簡單了,不是嗎?
  
  基本上,findViewById()方法仍在使用中。 可是沒有必要本身寫。 Kotlin會爲你作。
  
  當您使用Android擴展時,findCachedViewById()函數和HashMap實例將會自動生成。 每次經過其標識符訪問您的視圖將被一個新的函數調用替換。 若是是第一次訪問視圖,此函數將調用一般的findViewById()函數,並將接收的視圖添加到HashMap中,以便在下次訪問視圖時從中檢索視圖。
  
  5. 你能夠更容易地使用集合
  
  讓咱們談談Kotlin的集合。 由於咱們常常須要使用數據模型集合執行困難的操做。 例如,咱們可能有一個學生名單,咱們須要從中檢索三個A級成績的學生和兩個B成績的學生。
  
  看看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)
  
  下面是咱們如何解決Java中的一樣的問題:
  
  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);
  
  }
  
  }
  
  這只是一個小例子,說明如何在Kotlin和Java中使用集合,但你能夠看到差異! 你能想象若是咱們處理一個大項目的集合,Kotlin會有什麼區別嗎?java

相關文章
相關標籤/搜索