Java入门第5节——类型转换和算术运算符

系列连载文章,大家可以从我的专栏学习Java入门基础知识,后续也会有更高级的Java特性、企业级开发框架,也有平常工作中的技术总结和分享,欢迎关注我的CDSN博客。同时可关注微信公众号“Java开发之旅”,获得更多技术资料! 

目录

闲言碎语

数据类型转换

算术运算符

有趣的++、--

“特殊”的算术运算符

“+”在字符串中的应用

算术运算符的优先级

小结


闲言碎语

在上一节中,我们认识了Java中的基本数据类型(四类八种),并且定义了这些类型的变量,那么在这一节当中,我们对数据类型和变量进行更深一步的学习。

 

数据类型转换

上节课当中,当我们声明变量时,敢于尝试的朋友会发现以下代码也可以正常运行:

public class Hello {
​
    public static void main(String[] args) {
        //左边声明的是double双精度浮点,右边赋的值却是整数
        double test = 1;
        //打印是没问题的
        System.out.println(test);
    }
}

what???double类型不是双精度浮点的小数吗?怎么会可以存储整数呢?

是的你没有看错,确实是可以的,只不过会自动升级为小数,这就是Java当中的数据类型转换在发挥作用。

在Java当中,有些数据类型之间是可以互相兼容、互相转换的,这个机制叫做数据类型转换,就是将等号右边的数据类型转换为左边的数据类型。

一般的,大的类型可以向下兼容小的类型,此时等号右边的小类型会自动提升为左边的大类型,叫做自动转换。拿所有的数值类型来说(boolean不存在自动转换和强转,char稍后结合String讲解),在不超过各自的取值范围的情况下,自动转换关系如下图所示:

上图中的每一个数据类型,都可以兼容它右边的所有数据类型,也就是说double可以兼容所有的数据类型,float可以兼容long、int、short、byte,以此类推。

所以以下代码都是合法的(注意看注释):

public class Hello {
​
    public static void main(String[] args) {
        //声明一个byte类型变量
        byte a = 1;
        //将byte类型赋值给short类型,合法
        short b = a;
        //将short类型赋值给int类型,合法
        int c = b;
        //将int类型赋值给long类型,合法
        long d = c;
        //将long类型赋值给float类型,合法
        float e = d;
        //将float类型赋值给double类型,合法
        double f = e;
​
        //由于自动转换时,会提升数据类型,所以变量e的值已经不是1了,而是1.0,所以此处输出1.0
        System.out.println(e);
        
        //虽然变量f是双精度浮点,但是因为它的值是由变量e而来,所以这里其实f的值是1.00,
        //只不过我们没有指定格式,Java为我们省略了最后的一个0,所以这里也输出1.0
        System.out.println(f);
​
        /*
        *   以上赋值链说明,数据类型可以向下兼容,而且可以跨层级兼容
        *   比如double兼容float,而float又兼容long,long又兼容int……
        *   以此类推,所以double兼容所有的数值类型,其他的向下兼容同理。
        * */
    }
}

上面是向下兼容,如果我们要向上兼容呢?比如将一个int类型的变量赋值给short类型的变量,这就需要short兼容int,属于向上兼容。

这就需要我们手动转型,也叫做强制转换。我们只需要在值的前面用英文的小括号说明我们要转换的类型,就可以实现强制转换

public class Hello {
​
    public static void main(String[] args) {
        int a = 1;
        //使用语法进行强制转换:(转换的类型)
        short b = (short) a;
        System.out.println(b);
    }
}

如果要将float或者double转换为整型的int、long等,会丢掉小数点后的精度:

public class Hello {
​
    public static void main(String[] args) {
        double a = 5.3;
        //将浮点型转为整型
        int b = (int) a;
        
        // 输出5。
        // 注意这里不是四舍五入,只是简单的丢掉小数点之后的部分,
        // 就算a的值是5.9,也会输出5
        System.out.println(b);
    }
}

另外,前面我们说过,大类型兼容小类型会自动转换,当然我们也可以自己强制转换,只不过编辑器会提醒你不必这么做:

至于其他的强转,大家可以自由的去编写,都是一样的道理,有问题给我发私信或者在下方评论~~~ 

 

算术运算符

Java中的算术运算符主要有:

这里顺便说一句,也有人觉得+=、-=、*=、/=、%=这几个也是算术运算符,我觉得它们不能列到上面的表格中,毕竟它们只是一种简洁的变身写法,只是上面几种的变形,在下文中也会给大家介绍。

先介绍简单的加减乘除、取余:

public class Hello {
​
    public static void main(String[] args) {
        int num1 = 1;
        int num2 = 2;
​
        //加,输出3
        System.out.println(num1 + num2);
        //减,输出-1
        System.out.println(num1 - num2);
        //乘,输出2
        System.out.println(num1 * num2);
        //除,取商,输出0
        System.out.println(num1 / num2);
        //取余,输出1
        System.out.println(num1 % num2);
    }
}

 

有趣的是,算术表达式的结果,会向表达式中更高级的数据类型转型,什么意思呢?看一段代码:

 

什么?short类型不就是整型吗?整型进行+1操作,有毛病吗?

原因是,Java当中所有的整数,默认是int类型,就像浮点数默认是double一样。语句a = a + 1中的1,是一个整数,整数默认是int类型,虽然a是short类型,但整体的a + 1这个算术表达式的运算结果就被提升为了int。虽然结果都是整数2,但它是一个int类型的2而不是short类型的2,等号右边是int,左边是short,显然要进行强转,我这么说大家懂了吗?

所以改成以下代码即是正确的,用括号将表达式括起来,提高优先级,再强转:

 

 

再举一个例子,以下代码是正确的:

 

虽然表达式a = a + 1中的1是int型,但是这里的a是long类型的,最后的结果会向类型更大的转换,也就是说会自动提升为long类型,所以是可行的。

同理,以下代码就是不可行的,就像我们上面说的那样,右边的运算结果提升为了long类型,左边却是int,显然是不行的:

 

 

基于上面所说的数据类型提升,显然存在以下结论:

当算术表达式中存在浮点数时,会提升为默认的浮点类型double,特别标注的除外。

什么意思呢?看一段代码:

 

整型提升为浮点型,我觉得很容易理解吧,你加了一个小数,运算结果为2.6,2.6当然是浮点型了!只不过Java中默认的浮点型是double,所以提升为了double。

如果我们将小数特殊标注为float,你就可以用float类型去接收运算结果:

 

乘、除、取余都一个道理,不再举例了。下面重点说说++、--,即自增和自减。

 

有趣的++、--

++和--是自增、自减运算符,值的变化幅度是1,即自增1、自减1:

public class Hello {
​
    public static void main(String[] args) {
        int a = 0;
        //自增1,等价于a = a + 1
        a++;
    }
}

自增和自减运算符只能直接作用于变量的身上,不能写在具体的数字身上,以下代码是错误的:

 

 

有趣的是,++、--可以写在变量的前面,也可以写在变量的后面,不同的地方有不同的执行机制,大家思考一下,以下代码的输出结果:

public class Hello {
​
    public static void main(String[] args) {
        int a= 1;
        //a++
        System.out.println(a++);
        //++a
        System.out.println(++a);
        
        System.out.println(a);
    }
}

最后的输出结果是:

 

 

为什么是1、3、3呢?这是因为,自增或自减写在变量之后,程序会先使用变量的值,再重新计算赋值;自增或自减写在变量之前,程序先重新计算赋值,再进行使用。区别就是先使用、还是先计算,++或--写在前面是先计算、再使用,写在后面是先使用、再计算

 

所以上述代码,在第6行先使用变量a的值进行打印,此时的变量值是1,所以打印出了1,紧接着将变量a的值自增1,变成了2;在第8行,由于++写在了变量之前,要先进行计算、再使用,先将a的值自增1,变成了3,然后再进行打印,所以打印出了3;最后的打印语句没有自增或自减,所以也打印3

 

再来一个例子:

public class Hello {
​
    public static void main(String[] args) {
        int a = 1;
        int b = ++a;
        int c = a++;
​
        System.out.println(b);
        System.out.println(c);
        System.out.println(a);
    }
}

上述代码的打印结果是2、2、3,在第5行先将a的值+1变成2,再赋值给b,所以b的值是2;然后在第6行,先使用a的值2赋给变量c,再将a的值+1变成3,所以此时c的值是2,a的值是3,故而我们的打印结果是2、2、3,大家明白了吗?

而且,自增、自减运算符有隐式的数据类型转换,以下代码正确:

 

 

自减运算符--也是一个道理,这里我就不再举例了。

 

“特殊”的算术运算符

接下来就介绍几个特殊的算术运算符:+=、-=、*=、/=、%=。

它们是基本算术运算符的变形,我们就拿+=举例:

public class Hello {
​
    public static void main(String[] args) {
        int a= 1;
        //意思是在a的基础上,+2
        a += 2;
        //输出3
        System.out.println(a);
    }
}

​以上代码中的算术表达式a += 2,等价于a = a + 2,是一种简写而已。那么同理,a -= 2等价于a = a - 2,a *= 2等价于a = a * 2……不再举例。

需要注意的是,同自增、自减运算符一样,此类运算符也有隐式的类型转换,所以以下代码是可行的:

 

“+”在字符串中的应用

“+”在数值类型的计算中表示加法,它还有一种用法,就是在String类型的字符串中表示拼接:

public class Hello {
​
    public static void main(String[] args) {
        String str = "你好,";
        //使用+进行拼接
        str = str + "Java开发之旅";
        //输出  你好,Java开发之旅
        System.out.println(str);
    }
}

同样的,既然“+”可以用,“+=”也可以用:

public class Hello {
​
    public static void main(String[] args) {
        String str = "你好,";
        //等价于 str = str + "Java开发之旅";
        str += "Java开发之旅";
        //输出  你好,Java开发之旅
        System.out.println(str);
    }
}

而且,String类型是更大的数据类型,它可以使用“+”兼容所有的8种基本类型,表达式的结果会被提升为String字符串,注意只能是“+”进行字符串的拼接,其余的乘除减法等等都是不成立的:

public class Hello {
​
    public static void main(String[] args) {
        //输出  a的值是:1
        int a = 1;
        String str = "a的值是:" + a;
        System.out.println(str);
        
        //输出  b的值是:5.6
        double b = 5.6;
        str = "b的值是:" + b;
        System.out.println(str);
        
        //由于这里的1是字符串的“1”,所以虽然用了+=2,但只是字符串的拼接,输出字符串的“12”
        str = "1";
        str += 2;
        System.out.println(str);
    }
}

在后面我们讲到面向对象的时候,会专门用一篇文章来讲解String类,因为现在大家对类、方法、常量还没有概念,我们会逐渐深入。

 

算术运算符的优先级

Java当中的运算符有3种,算术运算符、关系运算符、逻辑运算符,在讲完这三种运算符之后会给大家汇总一个表。

基本的算术运算符,和我们在数学里的习惯是一样的:()、*、/、%、+、-,括号最大,往右递减之。

那+=、-=、*=……这些特殊的运算符,和基本的运算符结合起来是怎样的优先级呢?这里就留给大家思考的空间,大家下去自己尝试一下、总结一下,想想下面的执行结果:

public class Hello {
​
    public static void main(String[] args) {
        int a = 1;
        int b = a += 6 * 2 - 1;
        System.out.println(b);
    }
}

当然了,这里只是让大家总结,真正的开发中如果写成这样,会被同事骂死的,我们要用括号来提高优先级,这样代码的可读性也更高:

public class Hello {
​
    public static void main(String[] args) {
        int a = 1;
        int b = a += 6 * (2 - 1);
        System.out.println(b);
    }
}
public class Hello {
​
    public static void main(String[] args) {
        int a = 1;
        int b = (a += 6) * 2 - 1;
        System.out.println(b);
    }
}
public class Hello {
​
    public static void main(String[] args) {
        int a = 1;
        int b = a += (6 * 2) - 1;
        System.out.println(b);
    }
}

小结

以上就是第5节课的内容,你懂了吗?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章