【Java基础笔记】1-3 数据类型

§1-3 数据类型

计算机程序的运行往往需要不同类型数据的支持,本节将简单地介绍 Java 语言中的一些数据类型。

1-3.1 类型语言

Java 是一门典型的强类型语言,要求变量的使用需严格符合规定,所有的变量必须先定义后才可被使用,类似的强类型语言有 C 语言等。相对地,若类型语言对变量的规定较为宽松,例如 JavaScript 等。

1-3.2 数据类型

Java 的数据类型可以分为两大类:基本类型(primitive type)和引用类型(reference type)

下面这张图可简单地概括 Java 的数据类型:

image

1-3.2 创建数据类型

语法:Type <name> = <value>
下面是一些例子:

public example {
    public static void main(String[] args){
        //八大基本数据类型
        //整型
        //字节型:byte
        byte num1 = 10;
        
        //短整型:short
        short num2 = 32767;
        
        //整型:int
        int num3 = 100000;
        
        //长整型:long
        long num4 = 100000000L;		//为区别于整型,此处的L不可省略
        
        //浮点型
        //单精度浮点:float
        float num5 = 1.30F;			//为区别于双精度浮点型,此处的F不可省略
        //双精度浮点:double
        double num5 = 3.1415;
        
        //布尔型:boolean
        boolean val = true;
        
        //字符型:
        //字符:char
        char name1 = '国';			//仅能输出一个字符
        //字符串:String;
        String name2 = "一句话。"	//String首字母大写,它不是一个关键字,而是类。
        
    }
}

值得注意的是,当所定义的变量没有被赋值时,这时变量尚未初始化,是无法使用的。此外,所赋的值不属于其所定义的范围内也会出错。

1-3.3 数据类型扩展

1-3.3.1 整型扩展

我们知道,计算机所使用的常见进制有二进制、八进制、十进制、十六进制。在赋值变量时,所赋的值,在不加任何标识情况下,为十进制。若要赋值其他进制的数值,则需要在赋值时做出变化,需要在数值前添加一些字符。

赋值二进制:0b,八进制:0,十六进制:0x。如图所示

image

1-3.3.2 浮点扩展

由于浮点数并不是表示一个精确的数,因此,在进行浮点运算和浮点数比较时,往往会出现一些 “令人意想不到的” 结果,如图所示:

image

可以看到,f1d1数值一样的情况下,比较的结果却为false,同样地,还有:

image

也可以看到,当f2数值较大时,执行运算f3 = f2 + 1后再将f2f3作比较时,发现两者竟然相等,结果为true。综合上述两个例子来看,“等而不等” 、“等而不等” 体现了浮点数的两个特性:所表示的数接近而不相等,有舍入误差

因此,在执行较大数据的比较和运算,需完全避免使用浮点数来进行操作!
因此,在执行较大数据的比较和运算,需完全避免使用浮点数来进行操作!
因此,在执行较大数据的比较和运算,需完全避免使用浮点数来进行操作!

那么,在执行这类操作时,我们应转而使用BigDecimal,后续章节将会做出介绍。

另外,Java 还提供了一个关键字 strictfp,它用于修饰类、接口或方法(抽象方法、变量、构造器除外)。被该关键字修饰的类、接口、方法內部将使用严格的浮点数计算,声明范围内的所有浮点表达式会完全按照浮点规范 IEEE-754 执行。严格浮点数计算使得浮点计算在各硬件平台上所得结果一致,即浮点计算结果可预测。但是由于该关键字会对中间结果进行截断操作,这需要消耗时间,所以在计算速度上往往更慢。需要注意的是,采用严格浮点计算可能会产生溢出,而默认情况下,不会产生溢出。对大多数程序来说, 浮点溢出不属于大问题。

1-3.3.3 字符扩展

我们可以通过char命令单独输出一个字符。在这里,我们可以通过强制转换,将字符转换成其在编码表上对应的编码,并将该编码输出。键入如下代码:

public class code {
    public static void main(String[] args) {
        char c1 = 'a'
        char c2 = 'A'
        char c3 = '字'
        
        System.out.println((int)c1);
        System.out.println((int)c2);
        System.out.println((int)c3);
        System.out.println("=====================");
    }
}

得到输出结果如下所示:

image

可以看到,经过(int)的强制转换后,输出内容不再是字符本身,而是字符所对应的数字编码。这提醒我们,本质上,所有的字符都是数字。

目前常用的编码体系有 ASCII(American Standard Code for Information Interchange,美国标准信息交换码)、国标(中华人民共和国国家标准信息交换用汉字编码)、GBK等。

另外,我们还可通过转义字符实现常见的操作,例如制表、换行等。常用转义字符如下表列出:

转义字符 意义 转义字符 意义
\a 响铃(BEL) \b 退格(BS)
\f 换页(FF) \n 换行(LF)
\r 回车(CR) \t 水平制表
\v 垂直制表 \\ 反斜杠
\' 一个单引号 \" 一个双引号
\? 一个问号 \0 空字符(NUL)
\ddd 1到3位八进制数所代表的任意字符 \xhh 十六进制所代表的任意字符

下图展示了部分转义字符在输出时的作用:

image

1-3.3.4 布尔扩展

键入如下代码:

public class bool {
    public static void main(String[] args) {
        boolean flag = true;
        if (flag==true){}
        if (flag){}			//这两行 if 的意义是一样的,省略时默认表true
    }
}

1-3.4 数据转换

我们先来看看 Java 语言中以下数据类型的优先级:

低 ----------------------------------------------------------> 高

byte > short > char > int > long > float > double

实际上,这就是不同数据类型所占用的内存空间从小到大的排列顺序。

1-3.4.1 强制转换与自动转换

在进行数据之间的运算时,应先将不同类型的数据转换成同一类型后,在进行运算。类型转换有两种形式:强制类型转换自动类型转换。当数据由低转换至高时,转换自动进行;由高转至低时,则需要强制转换。如:

public class convert {
    public static void main(String[] args) {
        //自动转换
        char a = 'a'
        int num1 = a;
        
        System.out.println(a);
        System.out.println(num1);
        System.out.println("================");
        
        //强制转换
        int num2 = 128;
        byte num3 = (byte)num2;
        
        System.out.println(num2);
        System.out.println(num3);
        System.out.println("================");
    }
}

编译并运行,得到结果如下图所示:

image

值得注意的是,数据由高转换至低时,数据范围可能超出范围,此时会发生内存溢出现象。为成功转换,此时数据将会循环输出,如上述例子(int)128转换后超出了byte的范围,输出结果为-128。(参考原码、反码、补码 详解

另外,请看下面的例子:

public class calc {
    public static void main(String[] args) {
        int mon = 1_000_000_000;
        int y = 20;
        
        //转换与求值的先后问题
        long total1 = mon * y;
        long total2 = (long)mon * y;
        
        System.out.println(total1);
        System.out.println(total2);
    }
}

编译后运行,得到结果如下图所示:

image

从运行结果可以看到,Java 先对表达式作运算后再将结果转换成相应类型,致使出现溢出的错误结果。但若在计算前对目标数据类型进行转换后,结果正确输出。因此,建议先转换后输出

1-3.4.2 注意事项

  1. 布尔值不支持转换;

  2. 不能把对象类型转换为不相干的类型;

  3. 高容量转换为低容量时,需要强制转换;

  4. 转换时可能发生内存溢出或精度问题,例如:

    public class round {
        public static void main(String[] args) {
            float num4 = 24.15f;
            double num5 = -23.8;
            
           System.out.println((int)num4);
           System.out.println((int)num5);
        }
    }
    

    编译后运行,得到如下结果:

    image

posted @ 2021-07-10 20:56  Zebt  阅读(95)  评论(0)    收藏  举报