【数据类型转换、运算符、方法入门、编译器的常量优化】

数据类型转换:
当数据类型不一样的时候,需要发生类型转换。
Java当中的类型转换分为两种:

  1. 自动类型转换(隐式)
    特点:代码不需要进行特殊处理,自动完成。
    原则:只能从数据范围小的类型,转换为数据范围大的类型。(从小到大)

  2. 强制类型转换(显式)
    特点:代码需要进行特殊格式处理,不能自动完成。
    格式:小范围类型 变量名称 = (小范围类型) 原本大范围的数据;

注意事项:
1. 强制类型转换使用必须谨慎,因为有可能发生数据溢出、精度损失。
2. byte/short/char三种类型,都可以发生数学运算,例如加法。
3. byte/short/char三种类型,在发生运算的时候,都会首先向上提升成为int类型,然后再运算。
4. boolean类型不能发生类型转换。

强制转换数据溢出示意图:
这里写图片描述
char和int之间的转换对照关系表:
ASCII表:0-127分别代表不一样的字符。
Unicode表:万国码,0-127和ASCII完全一样,但是从128开始,可以包含更多字符。

        // 左边long,右边是int类型,不一样
        // 赋值就是把右边给左边,右边小范围,左边大范围
        // 所以这里发生了自动类型转换
        long num1 = 100;
        System.out.println(num1); // 100

        // 左边double类型,右边float,从小到大
        // 也发生了自动类型转换
        double num2 = 1.5F;
        System.out.println(num2); // 1.5

        // 左边float类型,右边long类型,从小到大
        // 也会发生自动类型转换
        float num3 = 300L;
        System.out.println(num3); // 300.0

        // 左边int类型,右边long类型,这就不是从小到大
        // 不能使用自动类型转换
        int num4 = (int) 400L;
        System.out.println(num4); // 400

        int num5 = 1300000000; // 13个亿
        System.out.println(num5); // 正常显示

        int num6 = (int) 6000000000L; // 60个亿
        System.out.println(num6); // 数据溢出

        int num7 = (int) 3.1;
        System.out.println(num7); // 3

        int num8 = (int) 3.9;
        System.out.println(num8); // 3,精度损失

        byte num9 = 10; // 注意右侧不能超过左侧的范围
        byte num10 = 20;
        System.out.println(num9 + num10); // 30

        // byte + byte --> int + int --> int
        int result1 = num9 + num10;
        System.out.println(result1); // 30

        // 右边的结果是30,我已经确定肯定不会超过byte的范围,
        所以可以谨慎使用强制类型转换
        byte result2 = (byte) (num9 + num10);
        System.out.println(result2);

        char zifu1 = 'A';
        System.out.println(zifu1); // A,65
        System.out.println(zifu1 + 1); // 66

        char zifu2 = 'B';
        System.out.println(zifu2 + 1); // 67

        char zifu3 = '中'; // 20013
        System.out.println(zifu3 + 1); // 20014

运算符:对数据进行操作的符号。
表达式:用运算符连起来的常量或变量,叫做表达式。

Java当中的常用运算符:
算术运算符
赋值运算符
比较运算符
逻辑运算符
三元运算符

算术运算符包括:
加 +
减 -
乘 *
除 /
模 %

注意事项:
1. 对于整数来说,除法使用的是小学一年级的算法:

 被除数 / 除数 = 商 ... 余数

2.如果运算当中有小数参与,那么结果直接就是小数。
3. 取模运算的典型应用:判断奇偶数。

        int a = 10;
        int b = 3;
        System.out.println(a - b); // 7

        // 只看商,不看余数
        System.out.println(a / b); // 3,商

        System.out.println(a % b); // 1,余数,模

        System.out.println(2.0 / 1.7);

算术运算符当中的加号,其实可以有多种用法。
1. 数学加法运算。
2. 还可以用于char类型,会首先提升成为int(查ASCII表/Unicode表),然后再运算。
3. 还可以用于字符串连接。

备注:任何数据类型和字符串进行+连接的时候,都会转换成为字符串形式。

        System.out.println("Hello" + 1); // Hello1
        // String + int + int
        // String       + int
        // String
        System.out.println("Hello" + 10 + 20); // Hello1020     
        System.out.println("Hello" + (10 + 20)); // Hello30

算术运算符当中的加号、减号可以双写,从而成为自增、自减运算符。
自增运算符:++,在一个变量本来数值的基础上,累加1。
自减运算符:- -,在一个变量本来数值的基础上,累减1。

使用格式:
1. 写在一个变量的前面。例如: ++a或者- -b
2. 写在一个变量的后面。例如: x++或者y- -

使用方式:
1. 单独使用:独立成为一个语句步骤,不和其他任何操作混合。
2. 混合使用:与其他操作一起混合,例如赋值语句、打印输出语句等等。

使用区别【重点】:
1. 在单独使用的时候,前++和后++没有任何区别。
2. 在混合使用的时候,前++和后++存在【重大区别】。
A. 如果是【前++】,那么变量【立刻马上+1】,然后拿着结果进行使用。(先加后用)
B. 如果是【后++】,那么变量先使用本来之前的数据,【然后变量再+1】。(先用后加)
注意:该加是一定会加的,只不过是先后时机不一样。

注意事项:
1. 只有变量才能使用这种运算符。
2. 这种运算符只需要一个变量就行,不需要两个或者更多。


        // 和打印语句一起混合使用
        int num3 = 30;
        System.out.println(++num3); // 31
        System.out.println(num3); // 31

        int num4 = 40;
        System.out.println(num4++); // 40
        System.out.println(num4); // 41

        // 和赋值语句一起混合使用
        int num5 = 50;
        int result1 = ++num5;
        System.out.println(result1); // 51
        System.out.println(num5); // 51

        int num6 = 60;
        int result2 = num6--;
        System.out.println(result2); // 60
        System.out.println(num6); // 59

        int a = 10;
        int b = 20;
        // 11 + 20
        int num = ++a + b--;
        System.out.println(a); // 11
        System.out.println(b); // 19
        System.out.println(num); // 31

赋值运算符

基本写法:
    =         代表将右侧的数据交给左侧的变量。

复合写法:
    +=      a += 3      a = a + 3
    -=      b -= 4      b = b - 4
    *=      c *= 5      c = c * 5
    /=      d /= 6      d = d / 6
    %=      e %= 7      e = e % 7

注意事项:
左侧必须是一个变量,才能赋值;右侧变量、常量无所谓。
比较运算符也叫做关系运算符:

大于        >
小于        <
大于等于    >=
小于等于    <=
等于        ==        【注意】
不等于      !=

结果一定是boolean值,如果成立就是true,如果不成立结果是false。

        int a = 10;
        int b = 20;
        System.out.println(a == b); // false
        System.out.println(a != b); // true
        System.out.println("=================");

        System.out.println(a == 15); // false
        // 强烈推荐不要写这种垃圾代码!
        // System.out.println(a = 15); // 15

        // 这才是优雅的代码,简洁明了!Wonderful!
        a = 15;
        System.out.println(a);

逻辑运算符主要分为四种(其中三种常用)

与(并且)   &   全都是true,才是true;否则就是false。
或(或者)   |   至少一个true,就是true;全都是false,才是false。
异或        ^   两个相同就是false;一样一个就是true。(了解即可,不太常用)
非(取反)   !   本来是true,变成false;本来是false,变成true

注意几点问题:
1. 这些逻辑运算符是作用在布尔数据上的。
2. 非运算符只需要一个数据,其他的都是左右各一个数据。
3. 如果遇到了类似于两个条件的判断(例如区间),那么不能连着写,一定要用逻辑运算符

例如:1 < x < 3      写成:    1 < x && x < 3
  1. 与(&)、或(|)两种运算符可以双写(&& ||),从而达到短路的效果。
    如果根据左侧已经可以确定最终结果,那么双写之后,右侧的代码将根本不执行。
    任何情况下都非常推荐始终使用双写的&&、||。
        // 双写形式,如果左边已经可以决定最终结果,右边根本不执行,
        从而提高一丢丢性能。
        int b = 20;
        // false && 无所谓
        System.out.println(3 > 4 && ++b < 30); // false
        System.out.println(b); // 20

一元运算:需要一个数据,例如:++ - - !
二元运算:需要两个数据,例如:+ - * /

三元运算,格式:

数据类型 变量名称 = 条件判断 ? 表达式A : 表达式B;

含义逻辑:
1. 首先进行条件判断,得到true或者false值。
2. 如果条件成立,那么取用表达式A的值。
3. 如果条件不成立,那么取用表达式B的值。

注意事项:
1. 三元运算表达式,结果必须被使用,不能不用。要么左侧赋值,要么打印输出。
2. 打印输出语句可以支持所有类型,但是如果左侧是变量,必须同时保证表达式A和表达式B符合类型要求。

        // 左边既没有变量接收,而且也不是打印输出,楞写 //错误
        // a > b ? a : b; // 错误写法!      
        // int num = 3 > 4 ? 10.0 : 20; // 错误写法!        
        // 要么右侧double --> 左侧double
        // 要么右侧int --> 左侧double
        double num = 3 > 4 ? 10.0 : 20;
        System.out.println(num); // 20.0

方法
定义:可以被当做是一种比类更小一级的大括号,是代码的更小组织单位。
基本格式(以今天的水平):

public static void 方法名称() {
    方法体
    return;
}

备注:
1. void代表方法不产生任何返回值。
2. 小括号之内留空,代表方法没有任何参数。
3. 方法体:就是希望这个方法做什么事情,可以是一行或多行代码。
4. 最后一行return;代表方法的结束,最后一行可写可不写。

注意事项:
1. 方法定义的前后顺序没有关系。
2. 方法的定义不能包含嵌套关系。(带有public static void的就叫做定义)
3. 方法定义之后,是不会主动自己运行的。如果希望执行方法,必须进行调用。

调用方法的格式(今天):

方法名称();
    public static void main(String[] args) {    
        seller(); // 调用小商贩的方法       
    }
    public static void seller() {
        System.out.println("运输到菜市场");
        System.out.println("吆喝");
    }

方法调用注意事项:
- 可以在main方法当中调用其他方法。
- 也可以在一个任意的方法当中,调用另一个方法。
- 方法的定义先后顺序不影响结果,调用顺序才会影响结果。
- 今天我们要尽量避免“循环调用”(今后学习的递归调用)。
a –> b –> a
a –> b –> c –> a
不能形成一个无限的环路。

  • 复合赋值运算符,其中隐含了一个强制类型转换。
        byte num3 = /*(byte)*/ 127;
        System.out.println(num3); // 127
  • 对于byte/short/char三者来说,只要赋值的右边不超过本类型的范围,那么编译器(javac)将会自动隐含地补上强制类型转换:(byte)(short)(char)。
    如果右侧的数值超过了左侧的范围,那么编译器将不会再做这种隐含强转,而会直接报错。
        byte num2 = 20;
        num2 += 3; // num2 = num2 + 3; 
        //--> num2 = int + int --> num2 = (int) int数据;
        System.out.println(num2); // 23
  • 编译器的常量优化
  • 如果一个表达式完全由常量组成,那么在javac编译的时候,就会直接计算出结果,放在.class字节码文件中。
    而此时此刻刚刚编译通过,还没有运行程序呢。
        // 如果没有编译器的常量优化,那么:
        // int + int --> int
        short num4 = 40 + 2; // .java文件中的代码,正确写法
        // short num4 = 42; // .class文件中的样子
        System.out.println(num4); // 42

.java –> javac –> .class –> java –> 运行结果
编译期 –> 运行期
编译器的常量优化,发生在编译期,而不是运行期。
只有常量才会有这种表达式优化;如果是变量就不会再优化了这里写代码片

        // 如果有变量,那么是不会进行这种优化的。
        int a = 10;
        // int + int --> int,因为有变量,所以编译期不再负责优化
        short num5 = a + 5; // 错误写法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值