毕向东Java基础教程-Java基础语法【上】

本篇为Java基础语法【上】,包含关键字、标识符、注释、原码反码补码、常量与变量、运算符这六部分内容。


关键字

定义:被Java语言赋予了特殊含义的单词。
特点:关键字中所有字母都为小写。

毕向东Java基础教程-Java基础语法【上】_第1张图片

标识符

定义:在程序中自定义的一些名称。由26个英文字母大小写数组:0-9符号:_$组成。
定义合法标识符规则:

  • 数字不可以开头
  • 不可以使用关键字

注意:

  • Java中严格区分大小写
  • 在命名时,为了提高阅读性,要尽量有意义
  • main不是关键字,因为函数名称都是标识符,只是JVM识别main函数,函数头的格式必须固定

注释

格式:

  • 单行注释 //
  • 多行注释 /* */
  • 文档注释 /** */

用途:

  • 注解说明
  • 调试程序

其中,单行注释中可以嵌套单行/多行注释,多行注释中可以嵌套单行注释,但不能嵌套多行注释;对于单行和多行注释,被注释的文字,不会被编译到字节码(.class)文件中,因此不会被JVM解释执行;文档注释为Java特有的注释,其中注释内容可以被JDK提供的工具javadoc.exe所解析,生成一套以网页文件形式体现的该程序的说明文档。

文档注释的一般写法:

/**
 * 用于操作数组的工具类,其中包含获取最值、排序等功能。
 * @author LoisHuang
 * @version 2019/7/9
 */
public class ArrayTool
{
    /**
     * 获取整型数组的最大值
     * @param arr 接收一个int类型的数组
     * @return 该数组的最大的元素值
     */
    public static int getMax(int[] arr)
    {
        ...
    }

}

注意可以通过javadoc命令生成说明文档的类和方法必须是由publicprotected修饰的,故私有的方法不用加文档注释,用多行注释写明功能即可。

tips:

  • 面试:上机题,写注释
  • 在看代码的时候,可以通过写注释来检验是否看懂(代码只是思想的一种表现形式)
毕向东Java基础教程-Java基础语法【上】_第2张图片

原码反码补码

(毕向东的Java基础教程中没有单独讲这一节的内容,但我认为对于后面的常量/变量以及运算符的理解非常有用。)
注意:原码和反码只是为了求负数的补码,在计算机中没有原码、反码的存在,只有补码。

原码

  1. 正数的原码就是它本身
    假设使用一个字节存储整数,整数10的原码是:0000 1010
  2. 负数用最高位是1表示负数
    假设使用一个字节存储整数,整数-10的原码是:1000 1010

反码

  1. 正数的反码和原码一样
    假设使用一个字节存储整数,整数10的反码是:0000 1010
  2. 负数的反码是负数的原码按位取反(0变1,1变0),符号位不变
    假设使用一个字节存储整数,整数-10的反码是:1111 0101

补码

再次强调,整数的补码才是在计算机中的存储形式。

  1. 正数的补码和原码一样
    假设使用一个字节存储整数,整数10的补码是:0000 1010(第三次强调:这一串是10这个整数在计算机中存储形式)
  2. 负数的补码是负数的反码加1
    假设使用一个字节存储整数,整数-10的补码是:1111 0110(第三次强调:这一串是-10这个整数在计算机中存储形式)

在计算机中,为什么不用原码和反码,而是用补码呢?

因为在使用原码、反码计算时不准确,使用补码计算时才准确。

  1. 使用原码计算10-10
          0000 1010  (10的原码)
       +   1000 1010  (-10的原码)
    ------------------------------------------------------------
          1001 0100  (结果为:-20,很显然答案是否定的。)

  2. 使用反码计算10-10
          0000 1010  (10的反码)
       +   1111 0101  (-10的反码)
    ------------------------------------------------------------
          1111 1111  (结果为反码,转换成原码为:1000 0000,最终的结果为:-0,很显然答案是否定的。)

  3. 使用补码计算10-10
          0000 1010  (10的补码)
       +   1111 0110  (-10的补码)
    ------------------------------------------------------------
         1 0000 0000  (使用的1个字节存储,只能存储8位,第9位的1没地方存,就被丢弃了。故结果为:0。)

常量与变量

常量

概念:表示不能改变的值。
分类:

  • 整数常量:所有整数
  • 小数常量:所有小数
  • 布尔(boolean)型常量:较为特有,只有true/false两个数值。
  • 字符常量:将一个数字、字母或符号用单引号' '标识
  • 字符串常量:将一个或者多个字符用双引号" "标识
  • null常量:只有一个null数值

在Java中,整数有四种表现形式:二/八/十/十六进制。因为十进制非0开头,所以其他进制的写法,要前补0用于区分。二进制:0b0B开头;八进制:0开头;十六进制:0x0X开头;负数前面加 -

变量

概念:内存中的一个存储区域,该区域有自己的名称(变量名)和类型(数据类型),数据可以在同一类型范围内不断变化。
变量使用的两个条件:有初始值和特定作用域。
数据类型:Java是强类型语言,对于每一种数据都定义了明确的具体数据类型,在内存中会分配不同大小的内存空间。

毕向东Java基础教程-Java基础语法【上】_第3张图片
  • 整数类型的存储空间大小分别为1, 2, 4, 8byte,最常用的类型是byteint,默认类型为int
  • 浮点型的存储空间大小分别为4, 8byte,默认类型为double
  • 字符型(char)的存储空间大小为2byte。

注意:由于整数类型默认为int,因此若一个大于int类型范围的整数常量赋值给long类型的变量时,结尾应该加上l,同理浮点型常量赋值给float类型的变量时,结尾加上f

Example1

long a = 1234567891234l;
float b = 2.3f;

类型转换&类型提升

针对于Java基础数据类型。

  1. 自动类型转换(隐式类型转换)
  • 两种类型是彼此兼容的

  • 转换的目的类型占得空间范围一定要大于转化的源类型
    正向过程:由低字节向高字节自动转换,byte->short->int->long->float->double
    Example1-1

    short i = 5;
    int j = i;
    

    Example1-2

     byte b = 4;   //注意4为int类型(任何整数都为int)
    

    编译器会判断4是否在byte范围内,如果在,则会做自动强转。

  1. 强制类型转换(显示类型转换)
    格式:目标类型 变量 =(目标类型)源类型变量/常量
    逆向过程:使用强制转换,可能丢失精度,如int a=(int)3.14;
    Example2-1

    int i = 5;
    byte j = (int)i;
    

    Example2-2

    byte b;
    b = 3;
    b = (byte)b*3    //编译出错,因为(byte)的运算级别比*高,所以会先转换b后再*3
    b = (byte)(b*3)  //正确
    
  2. 数据类型自动提升(注意以下讨论的是二元操作符)
    Java定义了若干使用于表达式的类型提升规则:
    a. 如果两个操作数其中有一个是double类型,另一个操作就会转换为double类型;
    b. 否则,如果其中一个操作数是float类型,另一个将会转换为float类型;
    c. 否则,如果其中一个操作数是long类型,另一个会转换为long类型;
    d. 否则,两个操作数都转换为int类型。
    (例外:final修饰的byteshortchar变量相加后不会被自动提升)
    Example3-1

    System.out.println('a');      //输出字母a
    System.out.println('a' + 1);  //输出98
    

    char型自动提升为int型。
    Example3-2

    byte a = 1; 
    byte b = 2;
    a = a + b;      //自动类型提升成int,编译出错
    a += b;         //自加没有自动类型提升问题
    

    把高字节转成低字节,需要作强制类型转换: a=(byte)(a+b);
    Example3-3

    byte b1 = 1, b2 = 2, b3, b6; 
    final byte b4 = 4,b5 = 6; 
    b6 = b4 + b5; 
    b3 = b1 + b2;   //会发生编译错误
    System.out.println(b3 + b6);
    

    没有final修饰的变量相加后会被自动提升为int型,与目标类型byte不相容,需要强制转换(向下转型)。
    Example3-4

    int x;
    int x1 = Integer.MAX_VALUE;
    int x2 = 2;
    x = x1 + x2;
    System.out.println(x);  //输出结果为-2147483647(其中Integer.MAX_VALUE为2147483647)
    

    默认int类型,运算一旦超出范围,会自动舍弃,保留原有位数。

注:Java内置Unicode国际标准码表,ASCII为美国标准码表,GBK为中国标准码表,任何国家的码表都兼容ASCII码表。

运算符

注意:运算符都是有结果的。

算术运算符

  • +正号,-负号
  • +-*/%,加减乘除取模
  • ++自增(前),++自增(后),--自减(前),--自减(后)
  • +字符串相加,连接符

Example1:整数除法运算

int x = 6370;
x = x / 1000; //x的结果为?

对于除号/,它的整数除和小数除是有区别的:整数之间做除法时,只保留整数部分而舍弃小数部分。Java为强类型语言,因此x/1000,两个int类型运算的值仍然为int类型。

Example2:负数取模运算

System.out.println(-5 % 2);   //输出-1
System.out.println(5 % -2);   //输出1

涉及到负数的模运算,只参考被模数(第一个数)。

Example3-1:自增运算

int a = 3, b;
b = a++;

实际上运算过程为:由于a本身涉及到与b的运算,因此会先开辟一个临时变量,存储a当前的值(怕a的值改变),如temp=3;而赋值运算需要等右边的运算先计算完成,于是现在计算右边的a++,计算完a+1后赋值给a,于是a=4;最后再将temp赋值给b,如下图所示:

毕向东Java基础教程-Java基础语法【上】_第4张图片

Example3-2:自增运算

int i = 3;
i = i++;
System.out.println("i=" + i); //输出i=3;

i = i++实际运算过程可理解为:

temp = i;
i = i + 1;
i = temp;

Example4-1:字符串相加

System.out.println(3 +"2");//输出32
System.out.println("5+5=" + 5 + 5);//输出5+5=55

+除字符串相加功能外,还能把非字符串转换成字符串。
第一步"5+5=5"+5,第二步"5+5=55";若要输出10,则可改为System.out.println("5+5="+(5+5));,输出5+5=10
任何数据只要和字符串进行+运算,都叫做相连接。用处如下:
Example4-2:同时输出a与b的值

int a = 4, b = 5;
System.out.println("a=" + a +",b=" + b);

Example5:注意

int a = 3;
a + 1;   //编译错误:a+1不是语句 
System.out.println("a=" + a);

赋值运算符

符号: =+=-=*=/=%=

Example1:+=简单示例

int a, b, c;
a = b = c = 4;
a += 2;   //将左右两边的和赋给左边 

Example2-1

short s = 3;
s = s + 4;//编译错误,可能损失精度
System.out.println("s=" + s);

Example2-2

short s = 3;
s += 4;
System.out.println("s=" + s); //输出s=7;

s = s + 4:编译失败,其为两次运算,s会被提升为int型,运算后的结果还是int型,无法赋值给short型。
s += 4:编译通过,其是赋值运算,为一次运算,与s = 3类似;+=运算符在给s赋值时,自动完成了强转操作,其在内存中的形式为s = (short)(s + 4)

比较运算符

符号:==!=<><=>=
instanceof 检查是否是类的对象,"Hello" instanceof String 结果为true
注意:比较运算符的结果都是boolean型。

逻辑运算符

定义:用来连接两个boolean类型的表达式,结果为boolean型。

毕向东Java基础教程-Java基础语法【上】_第5张图片

面试题 ——&&&的区别:
&:左边无论真假,右边都进行运算。
&&:若左边为真,右边参与运算;若左边为假,右边则不参与运算。
|||的区别同理,||:左边为真,右边不参与运算。

位运算符

注意在计算机系统中,数值一律用补码来表示和存储。

毕向东Java基础教程-Java基础语法【上】_第6张图片

位运算是直接对二进制进行运算。特定情况下,计算方便,速度快,支持面广;如果用算数方法,速度慢,逻辑复杂。位运算不限于一种语言,它是计算机的基本运算方法。

  1. <<
    相当于乘以2的倍数。
    应用:最有效率的方式算出2乘以8的值,首选位运算(左移三位)。

  2. >>
    符号位(最高位)是什么,就拿什么补空位。
    正数的右移相当于除法,右移n位就除以2的n次方(n表示移动位数),如100>>4 等效 100/2^4
    负数的右移不等于除法,即负数右移不能按除以2的n次方计算。

  3. >>>
    数据右移时,高位出现的空位,无论原高位是什么,空位都用0补。

  4. &
    应用:取一个数中的指定位。
    例如:设X=1010 1110,取X的低四位,用X & 0000 1111=0000 1110即可得到。
    方法:找一个数,对应X要取的位,该数的对应位为1,其余位为零,此数与X进行“与运算”可以得到X中的指定位。

  5. ^
    应用:
    1)与1相异或,使特定位翻转
    方法:找一个数,对应X要翻转的位,该数的对应为1,其余位为零,此数与X对应位异或即可。
    例如:X=1010 1110,使X低四位翻转,用X^0000 1111=1010 0001即可得到。
    2)与0相异或,保留原值
    例如:X^0000 0000 =1010 1110
    3)交换两个变量的值
    int a = 3, b = 5;
    a. 借助第三个变量来实现

    //开发时,使用第三方变量的形式,因为阅读性强
    int c;
    c = a;
    a = b;
    b = c;
    

    b. 利用加减法实现两个变量的交换

    //这种方式不要用,因为如果两个整数的数值过大,会超出int范围,数据会变化  
    a = a + b;     // a = 3 + 5;a = 8;
    b = a - b;     // 3+5-5 = 3;b = 3;
    a = a - b;     // 3+5-3 = 5; a = 5;
    

    c. 用位异或运算来实现,效率最高
    原理:一个数异或同一个数两次,结果还是这个数(即是一个数异或本身等于0且异或运算符合交换律)。

    //面试的时候用,阅读性差
    a = a ^ b;     // a = 3 ^ 5;
    b = a ^ b;     // b = (3 ^ 5) ^ 5; b = 3;
    a = a ^ b;     // a = (3 ^ 5) ^ 3; a = 5;
    
  6. ~
    对一个二进制数按位取反,即将0变为1,1变0。
    注意计算机中数值一律用补码来表示和存储,因此负数取反过程:先用原码表示,再转化为补码,补码取反,最后转化为原码,才是负数取反的值。

三元运算符

格式:(条件表达式)?表达式1:表达式2
如果条件为true,运算后的结果是表达式1;如果条件为false,运算后的结果是表达式2;

Example1:获取两个整数中的较大的整数

int a = 3, b = 4;
int max = a > b ? a : b;

Example2:获取三个整数中的较大的整数

int o = 3, p = 4, q = 5;
//易读的写法
int temp = o > p ? o : p;
int max = temp > q : temp : q;
//阅读性较差的写法
int max = (o > p ? o : p) > q : (o > p ? o : p) : q;

【参考文档】:
1、Java基础-原码反码补码
2、java 基本数据类型及自动类型提升
3、java中的二进制以及基本位运算
4、右移运算符总结

你可能感兴趣的:(毕向东Java基础教程-Java基础语法【上】)