从零开始学Java - Day02

今天,我们学习Java的一些基础知识,循序渐进,让我们慢慢的发现Java的魅力!

从零开始学Java - Day02

 

目录

一、Java须知的命名规则和规范

        1.1 标识符

        1.2 命名规范 

二、关键字和保留字 

三、八大基本数据类型 

        3.1、byte 

        3.2、short

        3.3、int

        3.4、long 

         3.5、float/double

         3.6、boolean

         3.7、char


一、Java须知的命名规则和规范

        1.1 标识符

        标识符,通俗意义上讲,就是我们程序员自己定义的名称,例如类名,方法名,变量名等等。也可以这样理解,只要需要我们自己起名字的,就是标识符。

        当然,名字也不能随便取,Java定义了合法标识符的规则:

        1)由26个英文字母大小写,0-9,_或者$组成

        2)数字不可以开头

        3)不可以使用关键字和保留字,但是可以包含关键字和保留字

        4)Java中严格区分大小写,长度没有限制

        5)标识符不能包含空格

        1.2 命名规范 

        我们除了要遵守标识符的规则,还要知道Java中命名的规范,规范的意义就是你不按照这个方式来命名,程序也不会报错,可是会显得很不正规,标准。命名规范就是我们程序员都会默认遵守的一些Java命名“规则”,是一种共识。

        1)包名

        在多个单词组合时,所有字母全部都小写。

        例如:testhelloworld

        2)类名、接口名

         在多个单词组合时,所有字母的首字母大写。

        例如:TestHelloWorld        (又名:大驼峰命名法

        3)变量名、方法名

         在多个单词组合时,第一个单词全小写,从第二个单词开始,后续单词全部首字母大写。

        例如:testHelloWorld        (又名:小驼峰命名法

        4)常量名

        在多个单词组合时,所以字母都大写,每个单词之间使用 _(下划线)来进行连接。

        例如:TEST_HELLO_WORLD 

注意:起名字时,我们为了提高阅读性,尽量起的名字做到“见名知意”。 

二、关键字和保留字 

        通过上面的学习,我们知道标识符是不能直接使用关键字和保留字来进行命名的,可是关键字和保留字都有哪些呢?让我们继续往下看。

关键字:就是在Java中具有特殊意义的字符,有表示数据类型、权限修饰等等
保留字:可以理解为目前还没有被使用,但是随着版本的更新,有可能会被使用的预备关键字 

从零开始学Java - Day02

 以上就是目前Java中的所有关键字和保留字了,总共53个。其中goto、const为保留字,其余都是关键字。在之后的学习中,就让我们来一个一个的攻克这些关键字吧!

三、八大基本数据类型 

从零开始学Java - Day02

        从上图可以看出,基本的数据类型分成了三大类:数值型、字符型、布尔型。数值型又细分成了两类:整数型和浮点型。 

        在这里我们引入一个概念:bit(binary digit)。bit是表示数据的最小单位。只有两种表现形式:0,1,可也理解为每一个二进制数字就是1bit。

        一个字节(byte)为8个比特,一个英文字母通常占用一个字节,一个汉字通常占用两个字节。普通计算机系统能读取和定位到最小信息单位是字节(byte)。

    1 Byte(B)= 8 bit
    1 Kilo Byte(KB)= 1024 B
    1 Mega Byte(MB)= 1024 KB
    1 Giga Byte(GB)= 1024 MB
    1 Trillion Byte(TB)=1024 GB   

从零开始学Java - Day02

         关于基本数据类型,这里先放个表格,以供参考,下面为大家一一解释。

从零开始学Java - Day02

        3.1、byte 

        byte 数据类型是8位、有符号的,以二进制补码表示的整数。byte 类型用在大型数组中节约空间,主要代替整数,因为 byte 变量占用的空间只有 int 类型的四分之一。我们可以先看一段代码:

public class ByteTest {
    static byte b;  //声明byte类型的变量b
    public static void main(String[] args) {
        System.out.println("byte的大小:" + Byte.SIZE);
        System.out.println("byte的的默认值:" + b);
        System.out.println("byte的取值范围:[" + Byte.MIN_VALUE + "," + Byte.MAX_VALUE + "]");
    }
}

        运行结果如下:

从零开始学Java - Day02

 根据运行结果,我们可以得到三个结论:

        1)1 byte 在Java中的大小为 8 bit;

        2)  byte 在Java中的默认值为 0;

        3)byte在Java中 最大值为127,最小值为-128;

//定义byte数据类型
        byte x = 100;
        byte y = -50;

那我们再深入思考一下,为什么byte的取值范围会是[-128,127],而不是[-128,128]呢?

首先,我们先了解一个运算规则:

        正数的最高位都是0,正数的值就是二进制表示的值。
        负数的最高位都是1,负数的值是取反后加1然后加个负号得到的值
我们简单的举个栗子理解一下:
        比如:0000 0001,这个二进制数字,最高位是0为正数,表示的是十进制中的1.

从零开始学Java - Day02      

        再比如1000 0001,最高位是1为负数,取反后得到0111 1110,再加上1得到0111 1111,换算成10进制值前面再加上负号,就得到了-127. 

从零开始学Java - Day02

         回到byte,我们已经知道了byte是8位的二进制数,可以推断出byte的最大正整数就是0111 1111,也就是127.那么byte的最小负整数呢?

        根据计算规则,我们可以推断出最小的负整数是1000 0000,进行取反就是0111 1111,再加1可以得出1000 0000,然后换算成十进制后加上负号,可以得出是-128

从零开始学Java - Day02

 我们现在已经知道了byte的最大正整数是127,那么如果我们将127再加1,结果会怎么样呢?

public class ByteTest {
    public static void main(String[] args) {
        byte b = 127;
        b += 1;
        System.out.println("b = " + b);
    }
}

让我们看一下运行结果:

从零开始学Java - Day02

 我们发现,当byte b = 127 + 1;时,结果居然是-128,这是为什么?

  这里我们需要先了解一些概念。对于一个数,计算机要使用一定的编码方式进行存储,而这个存储具体数字的编码方式有三种:原码、反码、补码。

原码:原码就是二进制数的符号位加上真值的绝对值,二进制数的第一位表示符号,其余位表示值。

        如:[+1]原 = 0000 0001; [-1]原 = 1000 0001;

反码:反码分为两种:正数的反码还是它本身,而负数的反码是在其基础上,符号位不变,其余位置全部取反。

        如: [+1]原 = 0000 0001 ;[+1]反 = 0000 0001;

                [-1]原 = 1000 0001 ;[-1]反 = 1111 1110;

补码:补码分为两种:正数的补码还是它本身。负数的补码是在其反码的基础上,再加1。

         如:[+1]原 = 0000 0001 ;[+1]反 = 0000 0001 ;[+1]补 = 0000 0001;
                [-1]原 = 1000 0001 ;[-1]反 = 1111 1110 ;[-1]补 = 1111 1111;

注意:想要求一个补码的原码,就是对这个补码再次补码。

为什么要使用反码和补码呢?

        因为让计算机去辨别符号位,其电路设计将会变得非常复杂,为了简化运算,人们想到了一种让符号位也参与运算的运算方式,我们都知道,减去一个数等于加上这个数的负数, 所以机器可以只有加法而没有减法, 这样计算机运算的设计就更简单了。

例如:

        1 + (-1) = [0000 0001] 原+ [1000 0001]原 = [1000 0010]原 = -2

        这样结果是错误的,所以引入了反码的概念,加入反码后我们再看:

        1 + (-1) = [0000 0001] 原+ [1000 0001]原 =  [0000 0001] 反+ [1111 1110]反 = [1111 11111] 反 = [1000 0000]原 = -0.

        这里我们可以看到,运算结果是对了,可是多了+0,-0两个数字,是没有意义的。于是,又引入了补码的概念。

        1 + (-1) = [0000 0001] 原+ [1000 0001]原 =  [0000 0001] 反+ [1111 1110]反 = [0000 0001]补 +[1111 1111]补 = [0000 0000]补 = 0;

        这样,之前的问题就都不存在了。

        int类型的128原码为0000 0000 0000 0000 0000 0000 1000 0000,在 byte += 1;的时候,发生了强制类型转换,因为byte只有8为二进制数,所以这里就截取了128原码的后8位,即1000 0000,转换成10进制后就得到了-128.

        为了加深映像,我们可以再看一段代码:

public class ByteTest {
    public static void main(String[] args) {
        byte b = -128;
        b += -1;
        System.out.println("b = " + b);
    }
}

运行结果如下:

从零开始学Java - Day02

 经过上面的学习,相信这里我们已经不难理解了。

int类型的-129原码为1000 0000 0000 0000 0000 0000 1000 0001;

补码为1111 1111 1111 1111 1111 1111 0111 1111;

强制转换为byte类型,只取后8位为:0111 1111;转换为10进制就为127了。

大家可以去做更多的尝试,这里就不再演示了。

        3.2、short

short 数据类型是 16 位、有符号的以二进制补码表示的整数.short 数据类型也可以像 byte 那样节省空间。一个short变量是int型变量所占空间的二分之一。

还是先看一下代码:

public class ShortTest {
    static short s;
    public static void main(String[] args) {
    System.out.println("short的大小:" + Short.SIZE);
    System.out.println("short的的默认值:" + s);
    System.out.println("short的取值范围:[" + Short.MIN_VALUE + "," + Short.MAX_VALUE + "]");
    }
}

运行结果如下:

从零开始学Java - Day02

根据运行结果,我们可以得到三个结论:

        1)1 short 在Java中的大小为 16 bit;

        2)  short 在Java中的默认值为 0;

        3)short 在Java中 最大值为32767,最小值为-32768;

//定义short数据类型
        short s = 1000;
        short r = -20000;

        3.3、int

int 数据类型是32位、有符号的以二进制补码表示的整数。一般地整型变量默认为 int 类型。看以下代码:

public class IntTest {
    static int i;
    public static void main(String[] args) {
        System.out.println("int的大小:" + Integer.SIZE);
        System.out.println("int的的默认值:" + i);
        System.out.println("int的取值范围:[" + Integer.MIN_VALUE + "," + Integer.MAX_VALUE + "]");
    }
}

运行结果如下:

从零开始学Java - Day02

根据运行结果,我们可以得到三个结论:

        1)1 int 在Java中的大小为 32 bit,占用4个字节;

        2)  int 在Java中的默认值为 0;

        3)int 在Java中 最大值为2147483647,最小值为-2147483648;

//定义int数据类型
        int a = 100000;
        int b = -200000;

 首先我们先来明确一下Java虚拟机在对int型数据进行处理时默认的两条规则:

        1. 当程序出现“整型常量”的时候,默认都是以int型存储的

        2.如果算术表达式中出现的所有的数字都是int型的,默认运算结果也是int类型

注意:
    需要注意一点:在程序编辑过程中,编译器只对直接出现的int常量进行超范围检查,
    但是对于在编译中算数运算、表达式产生的int型值则不会进行范围检查;

 为了方便我们理解,简单举个栗子:
        当我们将long类型数据赋值为9999999999时,并没有超出long类型数据的取值范围,但是编译器还是会报错。

从零开始学Java - Day02

         这是因为当程序中出现“整型常量”的时候,默认都是以int类型存储的。而”9999999999“ 就是直接出现的”整型常量“,所以编译器会把他当作int型看待。即使它被赋值给了long类型。
        我们知道,编译器会对”直接出现“的int常量进行数据超范围的检查,所以这里编译器将直接出现的整形常量“9999999999”看待int类型,并且进行数据超范围的检查,而经过检查这个数字已经超过了int类型所表示的范围,所以就会报错。
        这种情况的解决方法也很简单,只需在赋值的“整数常量”后面加上“L”即可 

从零开始学Java - Day02

        这是编译器能帮助我们识别的情况,我们还需要注意一些编译器无法帮我们识别的时候:

/**
 * 计算一天时间有多少微秒
 * (1小时=60分钟)
 * (1分钟=60秒)
 * (1秒=1,000毫秒)
 * (1毫秒=1,000微秒)
 */
public class MicrosecondTest {
    public static void main(String[] args) {
        //计算出一天的微秒数,考虑到结果超出了int类型的取值范围,使用long类型接收
        long microsecond = 24 * 60 * 60 * 1000 * 1000;  //正确结果:86,4000,000,000
        System.out.println("microsecond = " + microsecond);
    }
}

运行结果如下:

从零开始学Java - Day02

        在上面的算式中,所有计算的整数常量都是int类型,所以每一步的运算结果都会被保存在一个int型的临时变量中,由因为计算出来的整数结果不是“直接出现的整数常量”,所以并不会对其进行范围检查。
        随着计算的进行,结果超过了int的取值范围,但是在没有进行范围检查的情况下,编译器还是将结果保留在了int类型的临时变量中,造成了一种“溢出”现像,和之前byte类型中说的情况一样,int类型取值时会将超出取值范围的高位部分舍弃,保留取值范围内的数字,最后得到了一个错误的结果。 

        想要解决这种情况,只需在计算结果超出int取值范围之前,将其转换成long类型即可。

/**
 * 计算一天时间有多少微秒
 * (1小时=60分钟)
 * (1分钟=60秒)
 * (1秒=1,000毫秒)
 * (1毫秒=1,000微秒)
 */
public class MicrosecondTest {
    public static void main(String[] args) {
        //计算出一天的微秒数,考虑到结果超出了int类型的取值范围,使用long类型接收
        long microsecond = 24L * 60 * 60 * 1000 * 1000;  //正确结果:86,4000,000,000
        System.out.println("microsecond = " + microsecond);
    }
}

运行结果如下:

从零开始学Java - Day02

        除此之外,还有一种情况:

public class IntTest {
    public static void main(String[] args) {
        //定义一个int类型中的最大值
        int a = 2147483647;
        try {
            //进行循环,根据代码,好像这个代码只能循环10次
            for (int i = a - 9; i <= a; i++) {
                //将i的值打印出来
                System.out.println(i);
                Thread.sleep(1000);//每循环一次等1秒钟
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

运行结果如下:

从零开始学Java - Day02

        从这个结果中,我们可以看出,看上去只能执行10次循环,可当 i 的值等于int类型的最大数时,再进行 i++运算,其结果就会变成 i = -2147483648。最终,形成一次死循环。        

        3.4、long 

long 数据类型是 64 位、有符号的以二进制补码表示的整数。这种类型主要使用在需要比较大整数的系统上。看以下代码:

public class LongTest {
    static long l;
    public static void main(String[] args) {
        System.out.println("long的大小:" + Long.SIZE);
        System.out.println("long的:默认值" + l);
        System.out.println("long的取值范围:[" + Long.MIN_VALUE + "," + Long.MAX_VALUE + "]");
    }
}

运行结果如下:

从零开始学Java - Day02

根据运行结果,我们可以得到三个结论:

        1)long 在Java中的大小为 64 bit,占用8个字节;

        2)  long 在Java中的默认值为 0;

        3)long 在Java中 最大值为9223372036854775807,最小值为-9223372036854775808;

//定义long数据类型
        long a = 100000L;
        long b = -200000L;

 这里我们需要注意:
    当我们对long类型数据赋值时,被赋值的数值不超过int类型的取值范围时,是可以不用在数值后面添加L的,如:

long num = 100;	//num long类型,100 int类型
long num2 = 100L;	//num2 long类型,100L long类型

        这两种定义方式都是可以的,因为在Java中,long > int > short > byte, 而小的数据类型转换成大的数据类型,是会自动转换的,不过为了更好地区分int类型和long类型,我们最好在给long类型的赋值的时候,后面都加上一个L。

注意: 

   "L"理论上不分大小写,但是若写成"l"容易与数字"1"混淆,不容易分辩。所以最好大写。

         3.5、float/double

float和double,都是浮点型数据类型。
float 数据类型是单精度、32位、符合IEEE 754标准的浮点数;float 在储存大型浮点数组的时候可节省内存空间;
double 数据类型是双精度、64 位、符合 IEEE 754 标准的浮点数;浮点数的默认类型为 double 类型;

/**
 * float和double的测试类
 */
public class FloatAndDoubleTest {
    static float f;
    static double d;
    public static void main(String[] args) {
        //float
        System.out.println("float的大小:" + Float.SIZE);
        System.out.println("float的默认值:" + f);
        System.out.println("float的取值范围:[" + Float.MIN_VALUE + "," + Float.MAX_VALUE + "]");

        System.out.println("=====================================================");
        //double
        System.out.println("double的大小:" + Double.SIZE);
        System.out.println("double的默认值:" + d);
        System.out.println("double的取值范围:[" + Double.MIN_VALUE + "," + Double.MAX_VALUE + "]");
    }
}

运行结果如下:

从零开始学Java - Day02

        单精度的小数位在计算机中只有23位(二进制),换算到十进制只能百分百保证6位十进制数字的精确度。不能百分百保证7位的精度运算。同理,双精度,小数位是52位(二进制),换算为十进制则只能百分百能保证15位。

注意:声明并初始化float是,格式为:float f = 1.0f; 而使用double时,可以有两种写法:(1)double d1 = 10.2d; (2)double d2 = 10.2; 因为浮点数在默认情况下,都是double类型。

         3.6、boolean

        boolean数据类型表示一位的信息,只有两个取值:true 和 false,这种类型只作为一种标志来记录 true/false 情况,true表示条件成立,false表示添加不成立。

        默认的值为false,其在储存时大小只有1位,由于计算机在处理数据时最小单位为1个字节,所以有些人也会说它是8位。

        boolean类型适用于逻辑运算,表示某个条件是否成立。一般用于程序的流程控制。

public class BooleanTest {
    public static void main(String[] args) {
        int age = 18;
        boolean result = age > 20;
        System.out.println("当age > 20时,result = " + result);

        result = age < 20;
        System.out.println("当age < 20时,result = " + result);
    }
}

运行结果如下:

从零开始学Java - Day02

         3.7、char

        char是字符类型,占2个字节,用单引号' '标识,只能放单个字符。可以直接赋值一个字符:字母、汉子、数字,也可以赋值一个数字范围:0~65565。
        根据设计,一个字符集中,每个字符都对应一个数值。比如ASCII 码表中,‘a’对应这数值是97。

/**
 * char的定义
 */
public class CharTest {
    public static void main(String[] args) {
        char a = 'a';   //任意单个字符,加单引号
        System.out.println("a = " + a);

        char a2 = '中';  //任意单个中文字,加单引号。
        System.out.println("a2 = " + a2);

        char a3 = 111;  //整数。0~65535.输出字符编码表中对应的字符
        System.out.println("a3 = " + a3);

        char a4 = 'a' + 1;  //自动转换为int类型,输出对应编码表中的字符
        System.out.println("a4 = " + a4);

        char a5 = 'a' + 'b';    //自动转换为int类型,输出结果
        System.out.println("a5 = " + a5);

        char a6 = '中' + 1;  //自动转换为int类型,输出对应的字符
        System.out.println("a6 = " + a6);
    }
}

运行结果如下:

从零开始学Java - Day02

 根据运行结果,我们可以总结一下:

        1)char类型用单引号' '标识,只能放单个字符。
        2)char类型为数值时,表示的是这个数值在字符集中对应的字符。
        3)两个char字符的加减操作,运算的是其字符集对应的数值进行加减。结果为计算后的数值所对应的字符集

注意:

        char型变量是用来存储Unicode编码的字符的,unicode编码字符集中包含了汉字,所以,char型变量中可以存储汉字。不过,如果某个特殊的汉字没有被包含在unicode编码字符集中,那么,这个char型变量中就不能存储这个特殊汉字。

转义字符 :\

        转义字符出现在特殊字符之前会将特殊字符转换成普通字符。

        常见的转义字符有:

从零开始学Java - Day02

 我们通过一段代码来演示一下:

/**
 * 转义字符测试
 */
public class ESCTest {
    public static void main(String[] args) {
        char c1 = '\n';     //  '\n'换行符
        System.out.println("Hello," + c1 +"World!");
        System.out.println("==================");

        c1 = '\t';  //  '\t'缩进符
        System.out.println("Hello," + c1 +"World!");
        System.out.println("==================");

        c1 = '\'';  //  '\''单引号
        System.out.println(c1 + "Hello,World!" + c1);
        System.out.println("==================");

        c1 = '\"';  //  '\"'双引号
        System.out.println(c1 + "Hello,World!" + c1);
        System.out.println("==================");

        c1 = '\\';  //  '\\'反斜杠
        System.out.println(c1 + "Hello,World!" + c1);
        System.out.println("==================");
        
    }
}

运行结果如下:

从零开始学Java - Day02

        以上就是今天学习的全部内容了,有些可能需要学习到后面才能理解,大家可以先了解了解,加深下印象。 

上一篇:流程控制Day02


下一篇:day02