让我们从一些基本的语法差异开始。 这是第一个:
我们准备了一系列文章,分享我们在 Kotlin 开发 Android 应用程序的经验。 我们将讨论 Kotlin 与 Java 在语法,可用性,UI 性能和异步性方面的区别,以便您可以决定哪种语言最适合您。
Kotlin 比 Java 更年轻,但它是一个非常有前途的编程语言,它的社区不断增长。 每个人都在谈论它,并说它很酷。 但为什么这么特别?
Kotlin 的一个主要优点是它的简洁。 你用更少的代码获得更多的功能。 而你写的代码越少,你犯的错误就越少。 这很简单。 让我们看看 Kotlin 的基础知识,从类开始。
- public final class Person {privateString name;private intage;private floatheight;public Person(String name,intage,floatheight) {this.name = name;this.age = age;this.height = height;
- }public Person(String name,intage) {this.name = name;this.age = age;this.height =1.8f;
- }publicStringgetName() {returnname;
- }public void setName(String name) {this.name = name;
- }public int getAge() {returnage;
- }public void setAge(intage) {this.age = age;
- }public float getHeight() {returnheight;
- }public void setHeight(floatheight) {this.height = height;
- }@Override
- publicStringtoString() {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;returnname !=nullname.equals(person.name) : person.name ==null}@Override
- public int hashCode() {intresult = name !=nullname.hashCode() :0;
- result =31* result + age;
- result =31* result + (height != +0.0fFloat.floatToIntBits(height) :0);returnresult;
- }
- }
上面是一个通常的 Java 类。 它做的不多。 它只包含一些数据。 但是,当你意识到它给表带来的不足时,看看这段代码有多大是很痛苦的。 为了鼓励你,我们会给你一个等同的类写在 Kotlin。
是的,你会为你的数据类自动获取需要的 getters,setters,equals(),hashcode(),toString()和 copy()函数! 当然,你可以轻松地重写这些函数,但在大多数情况下,只需声明类及其属性就足够了。这正是我们的意思,当我们说 Kotlin 简洁。
- data classPerson(var name: String,
- var age: Int,
- var height: Float =1.8f)
- NullPointerException
如果变量是可空的,编译器将不允许你访问它没有适当的检查。 Kotlin 强迫你使用? 运算符。 这可以防止应用程序自动崩溃。它如何在引擎盖下工作? 让我们回顾一下生成的字节码。
- val person: Person? =null...
- person?.name ="John"
正如你所看到的,我们在这里有相同的空检查。 JetBrains 的开发人员(创建 Kotlin)知道每次检查我们的变量是避免 NullPointerException 的唯一方法。 但他们也知道 Android 开发人员不想在他们的项目中处理 NullPointerException。 他们可能想:" 为什么不自动生成这个检查如果变量是可空的?JetBrains 的开发人员只是这样,让我们的生活更容易了!
- L2
- LINENUMBER18L2
- ALOAD3DUP
- IFNULL L3
- LDC"John"INVOKEVIRTUAL igalata/com/kotlinexample/Person.setName (Ljava/lang/String;)VGOTOL4
- L3
- POP
- fun Context.toast(text: String) = Toast.makeText(this, text, Toast.LENGTH_SHORT).show()
注意'this',我们作为参数传递给 makeText()方法? 它不是类的一个实例,我们声明这个函数,而是一个 Context 实例。 现在你可以直接从你的 Activity 或任何其他 Context 实例调用这个函数。 例如:
- toast("Hi")
你应该记住,扩展函数不以任何方式修改它扩展的类。 那么它如何工作而不改变原来的类? 让我们再次看到字节码。
哈! 您的函数隐式接收它作为第一个参数扩展的类的实例。 因此,在字节码中,对函数体中 "this" 的任何访问都将替换为对第一个参数的访问。 没有魔法真的。 您可以在项目的任何位置使用此函数。时间删除你的 util 包!
- public final toast(Landroid/content/Context;Ljava/lang/String;)V
- @Lorg/jetbrains/annotations/NotNull;()// invisible, parameter 0
- @Lorg/jetbrains/annotations/NotNull;()// invisible, parameter 1L0
- ALOAD1LDC"$receiver"INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull (Ljava/lang/Object;Ljava/lang/String;)V
- ALOAD2LDC"text"INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull (Ljava/lang/Object;Ljava/lang/String;)V
- L1
- LINENUMBER31L1
- ALOAD1ALOAD2CHECKCAST 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
- LINENUMBER32L2
- RETURN
- L3
- LOCALVARIABLEthisLigalata/com/kotlinexample/MainActivity; L0 L30LOCALVARIABLE $receiver Landroid/content/Context; L0 L31LOCALVARIABLE text Ljava/lang/String; L0 L32MAXSTACK =3MAXLOCALS =3
这太简单了,不是吗?基本上,findViewById()方法仍在使用中。 但是没有必要自己写。 Kotlin 会为你做。当您使用 Android 扩展时,findCachedViewById()函数和 HashMap 实例将会自动生成。 每次通过其标识符访问您的视图将被一个新的函数调用替换。 如果是第一次访问视图,此函数将调用通常的 findViewById()函数,并将接收的视图添加到 HashMap 中,以便在下次访问视图时从中检索视图。
- 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);finalTextView text = (TextView) findViewById(R.id.text);
- button.setOnClickListener(newView.OnClickListener() {@Override
- public void onClick(View v) {
- text.setText("You've clicked a button");
- }
- });
- }
- }class MainActivity:AppCompatActivity(){override funonCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {super.onCreate(savedInstanceState, persistentState)
- setContentView(R.layout.activity_main)
- button.setOnClickListener { text.text ="You've clicked a button"}
- }
- }
- 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 students = new ArrayList() {
- {
- 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 firstList = new ArrayList < >();
- ArrayList 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 会有什么区别吗?
来源: http://blog.csdn.net/sergeycao/article/details/54984108