本篇博客将对Java中的数据类型、操作符,常量与变量和数组进行介绍。这些内容都是Java中最基本的知识,也是初学Java时最开始就需要了解的东西。
Java数据类型
Java是一种强类型的语言,这就意味着编写Java代码时必须为每一个变量都声明一个类型,且每个变量只能被赋予与其类型匹配的值。Java中的数据类型可以分为基础数据类型和引用数据类型,两者间最大的差别是在计算机中的存储方式和位置不同。基础数据类型在创建时会在栈中分配一块内存,将数据直接存储在其中;而引用数据类型在被创建时,会在堆内存上分配一块内存,将数据内容存储在其中,并在栈中分配一块内存用于存储该数据在堆中的地址。
Java中包含8中基本数据类型,包括4中整数类型:short、int、long、byte,2中浮点类型:float、double,1种用于表示Unicode编码的字符单元的字符类型char和1种用于表示真假值的boolean类型。它们相关信息如图1所示
图1:各基本数据类型信息
在Java的8中基本数据类型中,出除了boolean不能与其他类型相互转换外,其他类型间可以相互转换。这几种数值类型之间的转换关系满足如图2的条件。其中当数据沿着箭头的方向进行转换时,不需要额外进行处理(如int转换为long),而逆着箭头进行转换时则需要进行强制类型转换,且有可能会损失数据精度(如将float转换为int)。这里需要注意的是,这里大部分箭头都是从存储长度短的数据类型指向存储长度长的数据类型,这很容易理解。但是long的长度是64位,float的长度是32位,但是箭头确实从long指向float。这是因为float虽然占用字节数比较少,但是由于其采用的是尾数+指数的方式来表示的,因此反而比long数据类型的范围更大(查看图1也可以发现),因此数据从long转向float不会损失精度。
图2:各数据类型间的转换
基本数据类型的声明不需要多说,在初始化数据时,整型数据默认为int类型,浮点型数据默认为double类型。如果要定义long类型数据需要在数据后加L,否则会编译错误;同理定义float数据时需要加F。如图3所示:
图3:long和float数据类型的定义与赋值
运算符
Java中的运算符包括算术运算符,位运算符,赋值运算符,比较运算符,逻辑运算符和三目运算符。
算数运算符包括+、-、*、/、%、++(自加)、--(自减)。其中,++和--操作属于一目运算符,它们只能对一个操作书进行运算,且可以放在操作数的前面和后面。两者差别在于当自加(自减)放在操作数前面的时候,先对操作数进行加一(减一)操作,然后进行表达式的运算;放在操作数后面时,先进行表达式运算,然后对操作数进行加一(减一)操作。
位运算符对整型数的二进制的每一位进行操作,包括以下七种:
& | 按位与,左右都为1时返回1,其余为0 |
| | 按位或,左右都为0时返回0,其余为1 |
~ | 非,0结果为1,1的结果为0 |
^ | 异或,左右相同时为0,不同时为1 |
<< | 左移运算 |
>> | 右移运算 |
>>> | 无符号右移运算 |
赋值运算符的作用是给变量赋值,Java中使用=进行赋值操作。其次,赋值操作符还可以和算出操作符和位运算符一起使用。例如 “+=”操作, x += 3 等同于 x = x + 3。扩展运算符和原表达式的结果是一样的,但是能够避免运算时类型转换的错误,如图4所示:
图4:图片来自《疯狂Java讲义》
比较运算符只返回true和false,表示比较式成立和不成立,包括==、>、>=、<、<=五种。
逻辑运算符对布尔类型的变量进行运算,返回结果也为布尔类型。包括以下几种:
&& | 短路与,左右均为true时结果为true,否则为false。当左侧为false时,不判断右侧结果 |
& | 不短路与,作用于&&相同,但不进行短路 |
|| | 短路或,左右均为false时为false,否则为true。当左侧为true时,不判断右侧结果 |
| | 不短路或,作用于||相同,但不进行短路 |
! | 非,操作数为true返回false,操作数为false返回true |
^ | 异或,两侧操作数相同为false,不同为true |
三目运算符是“?:”,先计算一个逻辑表达式的值,根据值得不同返回不同的值。c = a > b ? 0 : 1表示,当a > b是c为0,否则为0。
变量与常量
变量指程序运行中可以改变的值,常量值程序运行中不能改变的值。Java中定义常量使用final进行修饰,final除了可以修饰常量以外,还可以用于修饰方法和类。
使用final修饰一个引用变量时,改变量所指向的对象不可以被改变,但是变量内部的其他变量可以修改;
使用final修饰一个方法时,该方法不可以被覆盖;
使用final修饰一个类时,该类不可以被继承。
数组
Java数组的定义方式如下:
type[] arrName = new type[size];
type arrName[] = new type[size];
两种定义方式没有差别,type表示数组中元素的类型,可以是基本类型或引用类型,arrName是数组的名字,new type[size]为数组分配了长度为size的空间长度,元素的默认值与定义的type的默认值相同。
Java数组的初始化有两种方式:
public void arrayTest() {
//静态初始化,定义数组时就分配空间并赋值
int[] arr1 = {1,2,3}; //动态初始化
int[] arr2 = new int[3];
arr2[0] = 1;
arr2[1] = 2;
arr2[2] = 3;
}
二维数组的定义与一维数组类似,且并不要求每一维的大小相同
public void arrayTest() {
int[][] arr1 = {{1,2},{3,4},{5,6,7}}; int[][] arr2 = new int[3][3];
arr2[0][0] = 1;
arr2[1][2] = 2;
arr2[2][2] = 3; }
Java中有Arrays类,其中加入了一些对数组常用的操作,例如Arrays.sort(), Arrays.toString()等
Arrays.sort(arr1);//数组排序
System.out.println(Arrays.toString(arr1));//一维数组输出
System.out.println(Arrays.deepToString(arr2));//多维数组输出
参考文献
[1].疯狂Java讲义(第三版)
[2].Java编程思想 第四版