久违的写博客了!这段时间也算是加班完了累又不想学习,然后搁那疯狂的摸鱼。一直想开始记录学习kotlin都没时间,这次算是闲下来给自己个目标把kotlin学完吧!
kotlin和java一样都是有变量的,但是声明的方式有挺大的区别
//java 声明变量
int x; //默认值 0
String name; //默认值null
final int finalX = 5;
final String phone = "17712345678"
//kotlin
var x:Int = 0 //必须设置默认值
var name:String = "张三"
val finalX:Int = 5
val phone = "17712345678"
上面我们能看到区别,kotlin没有默认值,声明的时候必须设置值,统一用var
和val
作为声明 用:xxx
来说明参数的类型,甚至可以不声明什么对象让系统自动识别出来对象的类型。还有就是int
变成了Int
部分相应的字段变化如下
java | kotlin |
---|---|
byte | Byte |
char | Char |
short | Short |
long | Long |
float | Float |
double | Double |
引用链接
var number: Int = 1 // 还有 Double Float Long Short Byte 都类似
var c: Char = ‘c’
var b: Boolean = true
var array: IntArray = intArrayOf(1, 2) // 类似的还有 FloatArray DoubleArray CharArray 等,intArrayOf 是 Kotlin 的 built-in 函数
var str: String = “string”
我们发现基本都是使用了对象的形式,虽然原来的java也有但是我们一般都是用java自带的,这边要注意下使用对象形式的字段声明
上面我们看到kotlin是必须设置默认值的,就是为了解决开发人员99%的崩溃异常(因为基本都是NullPointerException崩溃[笑])
那我们就是要设置null初始对象呢其实也是可以的。
var x = null
var y:String? = null
lateinit var z: String //代表延迟初始化 需要在初始化中设置值
上面方式都可以设置为null,但是要记得处理NullPointerException
那么问题来了比如我们获取到一段服务器的数据,肯定字段有可能为空,我们应该如何处理呢!
class User {
var name:String? = null
var phone:String? = null
}
模拟使用如下
//模拟只获取到了name字段没有phone字段
var user = gson.fromJson("{name:\"李四\"}", User::class.java)
println("userName = ${user?.name}")
println("userPhone = ${user!!.phone}")
在使用的时候需要字段的时候加上?
或者!!
用来判断是否为空。
这两个区别在于
"?"加在变量名后,系统在任何情况不会报它的空指针异常。
"!!"加在变量名后,如果对象为null,那么系统一定会报异常!
我们在java中很常见的使用if也很简单,kotlin其实也一样只不过在这基础上加了一些功能而已
//java
int c = 4
String reslut = ""
if(c == 2){
reslut = "正确"
}else if(c > 2){
reslut = "太大了"
}else{
reslut = "太小了"
}
//kotlin
var = 3
var reslut = if(c == 2){
"正确"
}else if(c > 2){
"太大了"
}else{
"太小了"
}
可以看到if是可以直接返回值的,帮助减少多余的代码
when可以理解为java的switch,还是加强版
还是上面的案例
var reslut = when {
c == 2 -> "正确"
c > 2 -> "太大了"
else -> "太小了"
}
看着好像就是if的变化但是when其实是可以判断类型或者直接在一个when中做多样事情
var x = 11
var y = "kotlin"
var view:TextView? = null
when(view){
is TextView -> println("view is TextView")
is ImageView ,is ImageButton -> println("view is Image")
else -> println("I Do not know")
}
when {
x in 1..10 -> log("x in 1-10")
y.contains("k") -> println("$y contains k")
else -> println("I Do not know")
}
结果为
I Do not know
kotlin contains k
我们可以看到不管是默认的switch判断还是没有对象的多种判断(其实没有对象判断就是if-else的形式)when是一个很强大的条件语句
在原来java中我们for一般都是遍历数组,kotlin中是可以快速遍历数组和map等
我们这边用1-10的遍历写下kotlin的一些常用功能
for(i in 1..10){
println(i) //1 2 3 ... 10
}
for(i in 1 until 10){
println(i) //1 2 3 ... 9
}
for(i in 1..10 step 2){
println(i) //1 3 5 ... 9
}
for(i in 10 downTo 1){
println(i) // 10 9 8 ... 1
}
for(i in 10 downTo 1 step 2){
println(i) // 10 8 6 ... 2
}
上面我们能看到一些变化
java | kotlin |
---|---|
1 <= 10 |
1 .. 10 |
1 < 10 |
1 until 10 |
i+=2 |
step 2 |
倒序遍历(java需要自己手动修改) | downTo |
还有就是直接遍历list和map的简单示例
val array = arrayOf("a", "b", "c", "d")
for (value in array){
println(value) //a b c d
}
for (i in array.indices){
println(i) //0 1 2 3
}
for((i, value) in array.withIndex()){
println("$i=$value") //0=a 1=b ...
}
val map = mapOf("a" to 77, "b" to "kotlin", "c" to View(this))
for ((key, value) in map){
println("$key=$value") //a=77 b=kotlin c=android.view.View
}
java中的方法全部在kotlin中改为了fun
区别如下
//java
void main(){}
//kotlin
fun main(): Unit{} //Unit可以省略
fun main(){}
//java
int add(int a, int b){
return a + b;
}
//kotlin
fun add(a: Int, b: Int): Int{
return a + b
}
还有这边要提一下kotlin中不给fun
设置可见修饰符private
、public
等默认情况是public
遇到个别关键字的时候就不是public
了
java中创建类写法和kotlin区别也是有的,具体情况如下
//java
public class JavaC {
private String name = "JavaC";
public JavaC() {}
public JavaC(String name) {
this.name = name;
}
}
//kotlin
class KotlinC {
var name: String = "KotlinC"
constructor()
constructor(name: String) {
this.name = name
}
}
java中我们的构造函数是直接写类名而在kotlin中使用关键字constructor
代替
下面我们来说下属性的get set
在java中我们可以使用setXXX getXXX来实现属性的中转,由于java中没有空保护,所以我们一般都会在类的属性get方法中加入类似如下方法
private String name;
public String getName() {
return name == null ? "" : name;
}
用于过滤掉Null错误,也可以在这边实现强制修改值的功能等。在kotlin中我们需要在var的值下面直接调用get set方法和java区别挺大的,我们还是用上面的类做扩展 具体如下
public class JavaC {
private String name = "JavaC";
public JavaC() {
}
public JavaC(String name) {
this.name = name;
}
public String getName() {
return name + ".class";
}
public void setName(String name) {
this.name = "set " + name;
}
int add(int a, int b){
return a + b;
}
}
class KotlinC {
var name: String = "KotlinC"
//由于kotlin使用的是field代表变量所以必须直接写在变量下方
get(){
return field + ".kt"
}
set(value) {
field = "set " + value
}
constructor()
constructor(name: String) {
this.name = name
}
}
//具体使用
JavaC javaC = new JavaC();
javaC.setName("JC");
println(javaC.getName()); //set JC.class
val kotlinC = KotlinC()
kotlinC.name = "KC"
println(kotlinC.name) //set KC.kt
我们就用最常见的MainActivity用来说明
自动生成的代码如下
//java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
//kotlin
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
我们看到extends
被:
替代、注解@Override
被关键字override
替代
这边要说明下:
不仅可以代表extends
还可以代表implement
示例如下
interface Impl {}
//java
public class MainActivity extends AppCompatActivity implements Impl {}
//kotlin
class MainActivity : AppCompatActivity(), Impl {}
下面我们写一个最经常使用BaseActivity类
abstract class BaseActivity: AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(getLayoutId())
initView()
initData()
}
abstract fun getLayoutId(): Int
abstract fun initView()
abstract fun initData()
}
然后我们创建一个类继承他
class NewActivity: BaseActivity() {
override fun getLayoutId(): Int {
return -1
}
override fun initView() {
}
override fun initData() {
}
}
我们发现和java中基本一致,只需要实现抽象的方法就可以了。
这边我们说下override
在kotlin中是省略了protected
关键字,override
基本上是替代了protected
我们需要关闭override
的父类遗传的话只需要在override
前面加上final
关键字关闭遗传,比如之后我们在创建一个类继承NewActivity时候发现错误
class NewActivity2: NewActivity() {
//报错:This type is final, so it cannot be inherited from
}
发现类默认是final
修饰的,编译器建议我们添加open
字段,代码如下
open class NewActivity: BaseActivity() {}
之后我们新类就不会报错了!open
打开了默认的final
锁,而final
也可以锁住override
的遗传性
在java中我们用instanceof
判断参数是否是属于该类在kotlin中是使用is
,示例如下
首先我们先在NewActivity类中加入一个新的方法test NewActivity2中也继承并重写方法
open class NewActivity: BaseActivity() {
...//其他代码
open fun test(){
println("NewActivity test")
}
}
class NewActivity2: NewActivity() {
override fun test(){
println("NewActivity2 test")
}
}
然后我们调用方法
val new1:Activity = NewActivity()
val new2:Activity = NewActivity2()
if (new1 is NewActivity) {
new1.test() //NewActivity test
}
if (new2 is NewActivity) {
new2.test() //NewActivity2 test
}
我们发现kotlin帮我们省略了一些代码 在java中需要((NewActivity) new1).test()
这样实现
那么我们直接强转代码如下
//java
((NewActivity) new1).test();
//kotlin
(new1 as NewActivity).test()
如果我们强转失败呢,as
明显是可能转换失败的,这边还是使用kotlin的?
用来直接进行Null保护
val new3: Activity = MainActivity()
(new3 as? NewActivity)?.test()
这段代码直接就会不执行
算是kotlin基础开头的学习吧!继续学习了!
谷歌官方kotlin地址
Kotlin 的变量、函数和类型