【Java学习—(2)超详细的数据类型转换及运算符】

2 类型转换

在学习类型转换之前,我们先来学习什么是常量?

2.1 常量

常量是指运行时类型不能发生改变。

常量主要有两种体现形式:

2.1.1 字面量常量

10        // int 字面量常量(十进制)
010       // int 字面量常量(八进制),由数字0开头的
0x10      // int 字面量常量(十六进制),由数字0x开头
10L       // long字面量常量,也可以写为10l(小写的L)
1.0       // double字面量常量
1.5e2     // double字面量常量,科学计数法表示:1.5 * 10^2
1.0f      // float 字面量常量,也可写为1.0F
true      // boolean字面量常量,还有False
'a'       // char 字面量常量,单引号中只能写一个字符
"abc"     // String 字面量常量,双引号中可以有多个字符

2.1.2 final 关键字修饰的常量

public class Test {
    public static void main(String[] args){
        final int a = 10;
        a = 20;   //不能进行修改
        System.out.println(a);
    }
}

运行上面的代码,就会编译出错:

java: 无法为最终变量a分配值

2.2 类型转换

不同数据类型间(只有相同数据类型之间可以转换,数值型之间)的转换有:

  1. 小类型转为大类型

    小类型转为大类型是自动提升的,比如:

    a. 小类型的变量值赋值给大类型时,

    long b = 20; // 20默认为int字面量,此时int 类型提升为 long类型
    

    b. 小类型和大类型进行数学运算时,首先会将小类型提升为大类型而后进行数学运算

    public class Test {
        public static void main(String[] args){
            int a = 10;
            double b = 2.0;
            System.out.println(a / b); //输出为 5.0
        }
    }
    
  2. 大类型转为小类型

    大类型转换为小类型时需要强制类型转换,可能会丢失精度。(数据溢出或者数据部分丢失)

    public class Test {
        public static void main(String[] args){
            double a = 4.2;
            int b = (int)a;
            System.out.println(b); //编译结果为 4 
        }
    }
    

2.2.1 int -> long

public class Test {
    public static void main(String[] args) {
        int a = 10;
        //这里有一个隐藏的类型转换,整型字面量默认都是int,int->long
        //属于是小类型转换为大类型,自动提升
        long b = 20;
        //将int->long,自动提升
        b = a;
        //将long->int,无法直接转换,需要进行强制类型转换
        a = b;  //此时会报错
        a = (int)b; //需要进行强制类型转换
    }
}

a是一个整型,b是long类型,把一个long类型的变量赋值给int类型可能会导致整型变量放不下b的值

看下面这段代码

public class Test {
    public static void main(String[] args) {
        int a = Integer.MAX_VALUE; //int类型的最大值:2147483647
        long b = a+1;
        System.out.println(b);//编译结果为:-2147483648
    }
}

有人会问了,为什么最后结果和预想的不一样,不是已经变为long类型了么?

这是因为程序执行代码都是从右向左执行的,a(int) + 1(int) = int,此时已经溢出了,变为 -2147483648,long 接收的就是一个溢出后的值,并不是long类型放不下。

那我们应该怎么进行解决呢?

public class Test {
    public static void main(String[] args) {
        int a = Integer.MAX_VALUE;
        long b = a+1l;  //在常量1 后加 l(小写的L),变为long类型
        System.out.println(b);  //此时编译结果为:2147483648
    }
}

2.2.2 int->double

int :4字节

double: 8字节

属于小类型转变为大类型, int -> long 为自动提升

int / double -> double/double

小类型和大类型进行数学运算,会将小类型提升为大类型

2.2.3 int -> byte

byte : 1字节

int : 4字节

转换时,还是遵循大转小,强制转换;小转大,自动提升。

看下面代码:

byte a = 120;  //正常编译
byte b = 130; //此时报错,超过byte类型的数据大小,需要强制类型转换

在这里会有一个疑问?120 默认为int 字面量,属于 大转小,为什么不需要强制转换

这是因为对于数值型和字符型来说,小于4字节的数据类型(byte\char\short),在存储时会转换为4字节,byte类型在保存时会转为int类型。

在这里需要注意:

当把byte类型保存区间(-128 ~ 127)之内的整数赋值给byte时,可以直接赋值。超出

byte的范围,仍然需要强制类型转换

那么将一个int类型的变量赋值给byte时,可不可以直接赋值呢?

答案是:不可以,当把一个int变量赋值给byte时,无论是否超过保存范围,都需要进行强制类型转换。

byte a = 10;
byte b = 20;
byte c = a + b; //此时会报错

这里报错是因为, byte类型保存数据时会提升为int 类型保存的;小于4字节的数据类型(byte\char\short)CPU在读写数据时,都是以4字节为单位进行进行读取和写入的

所以需要强制类型转换。

byte a = 10;
byte b = 20;
byte c = (byte)(a + b); //输出:30

请看下面使用 final 修饰的变量

public class Test {
    public static void main(String[] args) {
        final byte a = 20;  //被final修饰,存储时还是byte 类型
        final byte b = 10;
        byte c = a + b;     //此时编译器不会报错
        System.out.println(c);
    }
}

因为,被final 修饰的变量除了数据值不能更改,类型也不能提升。

2.2.4 int <-> char

int : 4字节

char : 2字节(字符类型)

二者之间可以相互转化

计算机的内部都是0和1,char 字符会按照不同的编码规则转为int 类型存储

char ch = 'a';
int b = ch;   //char -> int 自动提升,按照Unicode编码将'a'转变为 int 
int c = 98;
char ch1 = (char)c;
System.out.println(b);   //输出:97
System.out.println(ch1); //输出:'b'

Unicode编码就是把不同的文字和字符按照一定的规则转为数字。

2.2.5 int <-> String

String : 字符串类型

int -> String的转换:

  1. 直接使用String对象 + int类型,进行拼接
  2. 使用String的valueOf方法
public class Test {
    public static void main(String[] args) {
        int a = 10;
        //使用String的valueOf方法
        String str1 = String.valueOf(a);
        //使用String对象 + 其他类型 ,转变为字符串
        String str2 = "" + a;
        System.out.println(str1);
        System.out.println(str2);
    }
}

String -> int的转换:

调用int 包装类的Intager.parseInt()方法

public class Test {
    public static void main(String[] args) {
        String str1 = "123";
        String str2 = "12sd34";
        int a = Integer.parseInt(str1);
        int b = Integer.parseInt(str2);
        System.out.println(a);  //输出为:123
        System.out.println(b);  //编译出错
    }
}

注意:当字符串包含了非数字时,转换会出错

2.3 数据类型的默认值

在Java中,所有数据类型都有默认值,定义变量后没有赋值的话,会有默认值

(只存在于类变量中,方法中的局部变量没有默认值)

public class Test {
    int a;
    long b;
    short c;
    byte d;
    char e;
    double f;
    float j;
    boolean h;
    String str;
    public static void main(String[] args) {
        System.out.println("int " + new Test().a);
        System.out.println("long " + new Test().b);
        System.out.println("short " + new Test().c);
        System.out.println("byte " + new Test().d);
        System.out.println("char " + new Test().e);
        System.out.println("double " + new Test().f);
        System.out.println("float " + new Test().j);
        System.out.println("boolean " + new Test().h);
        System.out.println("String "+ new Test().str);
    }
}

输出结果是:

int 0
long 0
short 0
byte 0
char  
double 0.0
float 0.0
boolean false
String null

3 运算符

3.1 算数运算符

算数运算符:+ - * / %

使用运算符时,要记住的点有:

  1. 相同类型进行数学运算,得到的值仍然是本类型
  2. 小类型和大类型进行数学运算时,先把小类型会提升为大类型,再进行运算
  3. 在除法运算中,0不能作为除数

% 称为取模运算,取余运算,不仅可以用于整数,小数也可以

有一个数 255,用取模运算得到它的个位,十位,百位?

个位:255%10 = 5

十位:255/10 = 25 25%10 = 5

百位:255/100 = 2

在这里, int / int = int ; 不想要被除数的几位,就除以10^n

3.2 增量赋值运算

增量赋值运算: += 、*= 、/= 、%=

a += 1 等同于 a = a+1

a %= 10 等同于 a = a %10

3.3 自增和自减运算符

自增: ++

自减: –

a++ : 先取a的值,再进行自增

++a:先自增,再取a的值

3.4 关系运算符

关系运算符:运算之后得到的都是布尔值

==相等
!=不等
<小于
>大于
<=小于等于
>=大于等于

3.5 逻辑运算符

逻辑运算符:运算后得到的是布尔值

&&逻辑与 (全真为真,有假则假)

两个操作数都是true,结果返回true;有一个false,就返回false

|| 逻辑或 (有真为真,全假为假)

两个操作数有一个为true,就返回true;都是false才会返回false

&& 和 || 都属于短路操作符

当使用多个条件逻辑与(&&)时,从左到右,有一个表达式为false,剩下的表达式就不用继续判断了,直接返回 false

当使用多个条件逻辑或(||)时,从左到右,有一个表达式为true,剩下的表达式就不用继续判断了,直接返回true

多个运算数为布尔值时,& 和 | 也可以表示逻辑运算,但是不满足短路操作符,所有的条件都要判断一遍。一般不推荐使用

! 取反

操作数为true,返回false;操作数为false,返回true

3.6 位运算符

位运算符:直接在二进制位上进行操作的运算符

按位与:&

有0出0,全1为1

按位或:|

有1为1,全0则0

按位取反: ~

该位为1,变为0; 该位为0,变为1

按位异或: ^

相异为1,相同为0

A ^ A = 0

A ^ B ^ A = A

3.7 移位运算

移位运算:

<< :左移

​ 最左侧位不要了,最右侧位补0

20<<1 20的二进制位向左移动1位

>>:右移

最右侧位不要了,最左侧位补符号位(正数补0,负数补1)

20>>1 20的二进制位向右移动1位

>>>:无符号位右移

最右侧位不要了,最左侧位补0

巧记:

左移1位相当于原数字*2

右移一位相当于原数字/2

3.8 条件运算符(唯一一个三目运算符)

表达式1 ?表达式2 :表达式3

当表达式1 为true时,取表达式2的值,否则取表达式3的值

3.9 注释

单行注释:一般用在方法中,给某一行做特殊说明 // 快捷键:ctrl + /

多行注释:不推荐 /* */

文档注释:一般用在方法和类的声明之前,告知用户该方法和类的使用原则 /** … */

  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值