Java面向对象系列[v1.0.0][数据类型]

分隔符 标识符和关键字

分隔符

Java语言里分号、花括号、方括号、圆括号、空格、圆点都具有特殊的分隔作用,统称为分隔符

标识符

标识符就是用于给程序中变量、类、方法命名的符号,必须以字母、下划线、美元符开头,后边可以跟任意数目的字母数字下划线美元符,此处的字母并不局限于英文26个字母,还可以是中文字符、日文字符等等

jshell> String 中国="China"
中国 ==> "China"
jshell> System.out.println(中国)
China
  • 不允许单独使用下划线作为标识符
  • 不能用Java关键字和保留字,但可以包含它们
  • 标识符不能带空格
  • 不能使用Java的三个特殊直接量:true/false/null
  • 只能包含美元符号,不能包含@、#等特殊字符

关键字

Java的关键字是一些具有特殊用途的单词,有特殊的使用因此不能当成变量名来用
在这里插入图片描述

数据类型分类

Java是强类型语言,强类型意味着两个方面。1:所有的变量必须先声明后使用;2:指定类型的变量只能接受类型与之匹配的值,这意味着每个变量和每个表达式都有一个在编译时就确定的类型,类型限制了一个变量能被赋的值,限制了一个表达式可以长生的值,限制了在这些值上可以进行的操作,并确定了这些操作的含义。
强类型语言在编译时会进行更严格的语法检查,声明变量的语法非常简单,只需要指定变量的类型和变量名即可,变量还可以使用其他修饰符,但变量至少需要指定变量类型和变量名,其中变量类型可以是Java语言支持的所有类型。
type varName[ = 初始值];
Java语言支持的类型分为两类:基本类型(Primitive Type)和引用类型(Reference Type);

  • 基本类型:包括boolean类型和数值类型,数值类型有整数类型和浮点类型,整数类型包括byte、short、int、long、char,浮点类型包括float和double;char代表字符型,实际上字符型也是一种整数类型,相当于无符号整数类型;
  • 引用类型:包括类、接口和数组类型,以及一种特殊的null类型,所谓引用数据类型是对一个对象的引用,对象包括实例和数组两种,实际上引用类型变量就是一个指针;
  • 空类型(null type):就是null值得类型,这种类型没有名称,因为没有名称所以不可能声明一个null类型的变量或者转换到null类型,空引用(null)是null类型变量唯一的值,它可以转换为任何引用类型但不能转换成基本类型(不能把null赋值给基本数据类型的变量),实际上在开发过程中可以忽略null类型,假定null只是引用类型的一个特殊直接量

整型

基本数据类型.png
int是最常用的整数类型,因此通常直接给出一个整数值默认就是当作是int类型,除此之外有几种情况:

  • 如果将一个较小的整数值(在byte或short类型范围内)赋给一个byte或short变量,系统会把这个整数值当成byte或short来处理
  • 如果用一个巨大的整数值(超出了int范围),Java并不会将其视作long型来处理,如果希望系统将其当作long型来处理,应在这个整数值后增加l或者L坐位后缀,通常用L
  • 可以将一个较小的整数值(在int类型范围内)直接赋给一个long型,Java虽然依然将其视作int处理,但int类型的值可以自动类型转换到long型
  • Java中整数值有4种表示方式,十进制、二进制、八进制和十六进制
public class IntegerValTest
{
    public static void main(String[] args)
    {
        // 下面代码是正确的,系统会自动把56当成byte类型处理
        byte a = 56;
        /*
        下面代码是错的,系统不会把9999999999999当成long类型处理,
        所以超出int的表数范围,从而引起错误
        */
        // long bigValue = 9999999999999;
        // 下面代码是正确的,在巨大的整数值后使用L后缀,强制使用long类型
        long bigValue2 = 9223372036854775807L;

        // 以0开头的整数值是8进制的整数
        int octalValue = 013;
        System.out.println(octalValue);
        // 以0x或0X开头的整数值是16进制的整数
        int hexValue1 = 0x13;
        int hexValue2 = 0XaF;

        System.out.println(hexValue1);
        System.out.println(hexValue2);

        // 定义二个8位的二进制数,二进制的整数以0b或者0B开头
        int binVal1 = 0b11010100;
        byte binVal2 = 0B01101001;
        // 定义一个32位的二进制数,最高位是符号位,符号位是1的时候表示他是个负数
        int binVal3 = 0B10000000000000000000000000000011;
        System.out.println(binVal1); // 输出212
        System.out.println(binVal2); // 输出105
        System.out.println(binVal3); // 输出-2147483645
        /*
         定义一个8位的二进制,该数值默认占32位,因此它是一个正数。
         只是强制类型转换成byte时产生了溢出,最终导致binVal4变成了-23
         */
        byte binVal4 = (byte) 0b11101001;
        /*
          定义一个32位的二进制数,最高位是1。
          但由于数值后添加了L后缀,因此该整数的实际占64位,第32位的1不是符号位。
          因此binVal5的值等于2的31次方 + 2 + 1
         */
        long binVal5 = 0B10000000000000000000000000000011L;
        System.out.println(binVal4); // 输出-23
        System.out.println(binVal5); // 输出2147483651
    }
}

所有数字在计算机底层是以二进制形式存在的,原码是直接将一个数值换算成二进制数,但计算机以补码的形式保存所有整数,补码的计算规则是,正数的补码和原码完全相同,负数的补码是其反码加1,反码就是对原码按位取反,只是最高位(符号位)不变
在这里插入图片描述
前边说到整数值默认是int类型,因此使用二进制形式定义整数时,默认占32位,第32位是符号位,如果在二进制整数后添加l或L后缀,这个二进制就占64位,第64位是符号位,因此long binVal5 = 0B10000000000000000000000000000011L;是个正数,然而0b11101001依然是个32位正整数,只是程序进行强制类型转换时发生了溢出,导致它变成了负数

字符型

字符型通常用于表示单个字符,字符型值必须用单引号括起来,Java使用16位的Unicode字符集作为编码方式,而Unicode被设计成支持世界上所有书面语言的字符,包括中文字符,因此Java程序支持各种语言的字符。
早期对英文字符、数字、标点符号等字符进行编号(8位,256个字符编号),计算机通过将这些编号转换为二进制进行保存,而ASCII字符集就是这些编号的总和,但是ASCII字符集不包含亚洲国家文字,因此又对世界上所有书面语言的字符进行了统一编号(16位,65536个字符编号),就有了Unicode字符集

字符型值有如下三种表示形式:

  • 直接通过单个字符来指定字符型值,例如‘A’、‘9’
  • 通过转义字符表示特殊字符型值,例如‘\n’、‘\t’
  • 直接使用Unicode值来表示字符型值,格式是‘\uXXXX’,其中XXXX代表一个十六进制的整数
    在这里插入图片描述
    字符型值也可以采用十六进制编码方式来表示,范围是‘\u0000’~‘\uFFFF’,一共65536个字符,其中前256个与ASCII码中的字符完全重合

因为计算机底层保存字符时,实际是保存该字符对应编码的二进制,因此char类型的值也可直接作为整型值来使用,相当于一个16位的无符号整数,范围是0~65535,因此其变量、值完全可以参与加减乘除等数学运算,也可以比较大小
如果把0~65535范围内的一个int整数赋给char类型变量,系统会自动把这个int整数当成char类型来处理

public class CharTest
{
    public static void main(String[] args)
    {
        // 直接指定单个字符作为字符值
        char aChar = 'a';
        // 使用转义字符来作为字符值
        char enterChar = '\r';
        // 使用Unicode编码值来指定字符值
        char ch = '\u9999';
        // 将输出一个'香'字符
        System.out.println(ch);
        // 定义一个'疯'字符值
        char zhong = '疯';
        // 直接将一个char变量当成int类型变量使用
        int zhongValue = zhong;
        System.out.println(zhongValue);
        // 直接把一个0~65535范围内的int整数赋给一个char变量
        char c = 97;
        System.out.println(c);
    }
}

char类型使用单引号括起来,而字符串使用双引号括起来,在Java语言中单引号,双引号和反斜杠都有特殊的用途,如果字符串中包含了这些特殊字符,则必须使用转义字符的表示形式,例如绝对路径“c:\code”则必须携程“c:\code”才会是期望的结果。

浮点型

Java的浮点类型有两种,float和double,他们有固定的范围和字段长度,并且字段长度和范围与机器无关,是遵循IEEE754标准,采用二进制数据的科学计数法来表示浮点数

  • float型数值(单精度浮点数):第1位是符号位,接下来8位表示指数,再接下来23位表示尾数
  • double型数值(双精度浮点数):第1位是符号位,接下来11位表示指数,再接下来的52位表示尾数
    Java浮点数使用二进制数据的科学计数法来表示浮点数,因此可能不能精确地表示一个浮点数,例如5.2345556f赋给一个float类型变量,然后输出它发现值变了,使用double类型时比float更精确,但如果浮点数的精度足够高(小数点后位数足够多),依然可能发生这种情况,因此如果想精确的保存一个浮点数,可以使用BigDecimal类

Java语言的浮点数有两种表示形式:

  • 十进制形式:这种形式就是简单的浮点数,例如5.12、512.0、.512,浮点数必须包含一个小数点,否则会被当成int类型处理
  • 科学技术形式:例如5.12e2(即5.12*102),5.12E2(也是5.12*102),必须指出的是只有浮点类型的数值才可以使用科学计数法形式表示

Java语言的浮点数默认都是double类型,如果希望Java把一个浮点类型值当成float类型处理,应该在这个浮点类型值后紧跟f或F,当然也可以在一个浮点数后添加d或D后缀,强制指定是double类型

Java还提供了3个特殊的浮点数:正无穷大、负无穷大和非数,用于表示溢出和出错,例如一个正数(浮点型)除以0将得到正无穷大(用Double或Float类的POSITIVE_INFINITY表示),负数(浮点型)除以0则得到负无穷大(用Double或Float类的NEGATIVE_INFINITY表示)0.0(浮点型)除以0.0(浮点型)或对一个负数开方将得到一个非数(用Double或Float类的NaN表示)。

所有正无穷大数值都是相等的,所有负无穷大数值都是相等的,而NaN不与任何数值相等,甚至和NaN都不相等。

public class FloatTest
{
    public static void main(String[] args)
    {
        float af = 5.2345556f;
        // 下面将看到af的值已经发生了改变
        System.out.println(af);
        double a = 0.0;
        double c = Double.NEGATIVE_INFINITY;
        float d = Float.NEGATIVE_INFINITY;
        // 看到float和double的负无穷大是相等的。
        System.out.println(c == d);
        // 0.0除以0.0将出现非数
        System.out.println(a / a);
        // 两个非数之间是不相等的
        System.out.println(a / a == Float.NaN);
        // 所有正无穷大都是相等的
        System.out.println(6.0 / 0 == 555.0/0);
        // 负数除以0.0得到负无穷大
        System.out.println(-8 / a);
        // 下面代码将抛出除以0的异常
//        System.out.println(0 / 0);
    }
}

数值中使用下划线分隔

Java7引入了新特性,数值中使用下划线,无论是整型数值还是浮点型数值,都可以自由的使用下划线,用于清楚的分辨数值位数

public class UnderscoreTest
{
    public static void main(String[] args)
    {
        // 定义一个32位的二进制数,最高位是符号位。
        int binVal = 0B1000_0000_0000_0000_0000_0000_0000_0011;
        double pi = 3.14_15_92_65_36;
        System.out.println(binVal);
        System.out.println(pi);
        double height = 8_8_4_8.23;
        System.out.println(height);
    }
}

布尔型

布尔型只有一个boolean类型,用于表示逻辑上的“真”和“假”,在Java中,boolean类型数值只能是true或false,不能用0或者非0来表示,其他基本数据类型的值也不能转换成boolean类型

public class BooleanTest
{
    public static void main(String[] args)
    {
        boolean b1 = true;
        boolean b2 = false;
        // 下面代码将出现错误:字符串不能直接变成boolean型的值
        // boolean b3 = "true";
        // 使用boolean和字符串进行连接运算,boolean会自动转换成字符串
        String str = true + "";
        // 下面将输出true
        System.out.println(str);
    }
}

基本类型的类型转换

在Java程序中不同的基本类型的值经常需要进行相互转换,类型转换方式有两种,一种是自动类型转换,另一种是强制类型转换

自动类型转换

Java所有的数值型变量可以相互转换,如果系统支持把某种基本类型的值直接赋给另一种基本类型的变量,则这种方式称为自动类型转换,只有一个数值范围小的值或变量直接赋给另一个范围大的变量时,系统才支持自动类型转换
在这里插入图片描述

public class AutoConversion
{
    public static void main(String[] args)
    {
        int a = 6;
        // int可以自动转换为float类型
        float f = a;
        // 下面将输出6.0
        System.out.println(f);
        // 定义一个byte类型的整数变量
        byte b = 9;
        // 下面代码将出错,byte型不能自动类型转换为char型
        // char c = b;
        // 下面是byte型变量可以自动类型转换为double型
        double d = b;
        // 下面将输出9.0
        System.out.println(d);
    }
}

当把任何基本类型的值与字符串进行连接运算时,基本类型的值将自动转换为字符串类型

public class PrimitiveAndString
{
    public static void main(String[] args)
    {
        // 下面代码是错的,因为5是一个整数,不能直接赋给一个字符串
        // String str1 = 5;
        // 一个基本类型值和字符串进行连接运算时,基本类型值自动转换为字符串
        String str2 = 3.5f + "";
        // 下面输出3.5
        System.out.println(str2);
        // 下面语句输出7Hello!
        System.out.println(3 + 4 + "Hello!");
        // 下面语句输出Hello!34,因为Hello! + 3会把3当成字符串处理,
        // 而后再把4当成字符串处理
        System.out.println("Hello!" + 3 + 4);
    }
}

强制类型转换

自动类型转换的图中,如果将箭头发过来,则必须进行强制类型转换(targetType)value,将范围大的往范围小的转换将会导致溢出,从而造成数据丢失,这种转换被称为“缩小转换(Narrow Conversion)”

public class NarrowConversion
{
    public static void main(String[] args)
    {
        var iValue = 233;
        // 强制把一个int类型的值转换为byte类型的值
        byte bValue = (byte) iValue;
        // 将输出-23
        System.out.println(bValue);
        var dValue = 3.98;
        // 强制把一个double类型的值转换为int
        int tol = (int) dValue;
        // 将输出3
        System.out.println(tol);
    }
}

溢出截取图

在这里插入图片描述

public class RandomStr
{
    public static void main(String[] args)
    {
        // 定义一个空字符串
        var result = "";
        // 进行6次循环
        for (var i = 0; i < 6; i++)
        {
            // 生成一个97~122的int型的整数
            var intVal = (int) (Math.random() * 26 + 97);
            // 将intValue强制转换为char后连接到result后面
            result = result + (char) intVal;
        }
        // 输出随机字符串
        System.out.println(result);
    }
}

当一个算数表达式中包含多个基本类型的值时,整个算数表达式的数据类型将发生自动提升:

  • 所有byte类型、short类型和char类型自动提升到int类型
  • 整个算数表达式的数据类型自动提升到与表达式中最高等级操作数同样的类型
public class AutoPromote
{
    public static void main(String[] args)
    {
        // 定义一个short类型变量
        short sValue = 5;
        // 下面代码将出错:表达式中的sValue将自动提升到int类型,
        // 则右边的表达式类型为int,将一个int类型赋给short类型的变量将发生错误。
        // sValue = sValue - 2;
        byte b = 40;
        var c = 'a';
        var i = 23;
        var d = .314;
        // 右边表达式中在最高等级操作数为d(double型)
        // 则右边表达式的类型为double型,故赋给一个double型变量
        double result = b + c + i * d;
        // 将输出144.222
        System.out.println(result);
        var val = 3;
        // 右边表达式中2个操作数都是int,故右边表达式的类型为int
        // 因此,虽然23/3不能除尽,依然得到一个int整数
        int intResult = 23 / val;
        System.out.println(intResult); // 将输出7
        // 输出字符串Hello!a7
        System.out.println("Hello!" + 'a' + 7);
        // 输出字符串104Hello!
        System.out.println('a' + 7 + "Hello!");
    }
}

直接量

并不是所有的数据类型都可以指定直接量,能指定直接量的通常只有3种类型:基本类型、字符串类型和null类型,具体可以给直接量的数据类型有:int、long、float、double、boolean、char、String和null

字符串直接量有一点需要指出,当程序第一次使用某个字符串直接量时,Java会使用常量池(constant pool)来缓存该字符串直接量,如果程序后面的部分需要用到该字符串直接量时,Java会直接使用常量池中的字符串直接量。

常量池,指的是在编译期间被确定,并保存在已编译的.class文件中的一些数据,它包括关于类、方法、接口中的常量,也包括字符串直接量

int a = 5;
char c = 'a';
boolean b = true;
float f = 5.12f;
double d = 4.12;
String author = "davieyang";
String book = "自动化测试";
String s1 = "hello";
String s2 = "hello";
String s3 = "he" + "llo";
System.out.println(s1 == s2);
System.out.printlb(s1 == s2);
发布了207 篇原创文章 · 获赞 124 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/dawei_yang000000/article/details/104948235