变量和数组
Java语言的基础主要包括变量,运算符,表达式,控制语句等编程语言最基础的内容。本文主要介绍Java数组和变量。
变量
java定义了以下类型的变量:
-
Instance Variables (Non-Static Fields)
相当于C++类的普通成员变量
-
Class Variables (Static Fields)
相当于C++中类的静态成员变量
-
Local Variables
方法通常会将其临时状态存储在局部变量中
-
Parameters
Parameters指的是方法的参数
java变量名的命名规则和C/C++类似,但是允许变量名中出现美元符号($),一般而言,java程序员是不使用美元符号的。
通常,java习惯上使用驼峰法命名。
基本数据类型
java和C/C++一样,是静态类型语言。因此,必须声明变量的数据类型。java支持8中的基本数据类型。如下表所示:
数据类型 | 占用字节 | 默认值 |
---|---|---|
byte | 1 | 0 |
short | 2 | 0 |
int | 4 | 0 |
long | 8 | 0L |
float | 4 | 0.0F |
double | 8 | 0.0D |
boolean | nan | false |
char | 2 | ‘\u0000’ |
定义变量的时候,如果没有给定初始值,那么默认的初始值为上表所示。需要特别注意的是,boolean占用的内存大小是不确定的。另外需要注意的是,java中的char是Unicode编码,16位的,意味着其支持65536个字符。
除了上面的8种类型之外,java.lang.String提供了String类型来支持字符串。该类型是不可变对象,这一点和Python中的字符串一样。
下面是一段代码来测试一下默认值和占用的字节大小。
public class variable {
int a;
short b;
int c;
long d;
float e;
double f;
boolean g;
char h;
void print(){
System.out.printf("%d\t%d\n",a, Byte.SIZE);
System.out.printf("%d\t%d\n",b, Short.SIZE);
System.out.printf("%d\t%d\n",c, Integer.SIZE);
System.out.printf("%d\t%d\n",d, Long.SIZE);
System.out.printf("%f\t%d\n",e, Float.SIZE);
System.out.printf("%f\t%d\n",f, Double.SIZE);
System.out.println(g);
System.out.printf("%c\t%d\n",h, Character.SIZE);
}
public static void main(String[] args) {
variable v = new variable();
v.print();
}
}
在Java8或者更高版本上,基本数据类型都存在一个对应的包装器,它们有一个SIZE属性来标识类型占据了多少位。其中Boolean类型是没有这个属性的。编译器永远不会为未初始化的局部变量分配默认值。如果无法在声明它的地方初始化局部变量,请确保在尝试使用它之前为其分配一个值。访问未初始化的局部变量将导致编译时错误。
还有一点对于java这样纯粹的面向对象语言,是非常奇特的,那就是基本类型的变量在初始化的时候,没有使用new关键字。这是因为,原始类型是语言中内置的特殊数据类型,它们不是从类创建的对象。
数组
数组是一个容器对象,它包含固定数量的单一类型的值。数组的长度是在创建数组时确定的。创建后,它的长度是固定的。数组的下标从0开始。这些和C/C++是一样的。下面是一个例子:
void array(){
int[] num = {1, 2, 3, 4, 5}; // 直接初始化,无需使用new。这种做法和C/C++一致
System.out.println(num[0]);
char[] str = new char[3]; // 先new一个char[3]大小的数组,然后让str变量引用这个数组。
str[0] = '1';
str[1] = '2';
str[2] = '3';
System.out.println(str[2]);
}
可以看到除了直接初始化之外,java还支持new一个数组,然后让变量去引用new出来的数组。第二种写法还可以分两步来完成。例如:
char[] str;
str = new char[3];
上述代码中的中括号[],可以放在变量名之前,也可以放在变量名之后,例如char str[]
,根据惯例是不鼓励将中括号放在变量名之后的。
多维数组
在Java中,多维数组是其元素本身就是数组的数组。这与C/C++中的数组不同。这样做的结果是允许行的长度不同。
String[][] names = {
{"Mr.", "Mrs.", "Ms."},
{"Smith", "Jones"}
};
System.out.println(names[0][1]); // 打印names的第0个元素中的第1个元素。
System.out.println(names.length); // 每个数组都有一个内置属性length,用来表示数组中元素的个数,这里打印2,表示names有两个元素
复制数组
由于java多维数组是其元素本身就是数组的数组,导致每一行的长度可能存在差异。因此对于多维数组而言,只能是复制了一维数组,然后在组装起来。System类提供了一个arraycopy方法来进行数组复制。
int[] num = {1, 2, 3, 4, 5};
int[] tmp = new int[5];
System.arraycopy(num, 0, tmp, 0, 5);
System.out.printf("%d\t%d\t%d\t%d\t%d\n", tmp[0], tmp[1], tmp[2], tmp[3], tmp[4]);
System.arraycopy方法的原型如下所示:
public static void arraycopy(Object src, int srcPos,
Object dest, int destPos, int length)
src表示原数组,srcPos表示要从原来数组的哪一个位置开始复制,dest表示要复制到的数组,destPos表示从dest数组的哪一个位置开始填充;length表示复制多少元素到dest数组。
数组操作
Java SE在java.util.Arrays类中提供了很多方法以方便数组操作,下面是常见的一些方法。
int[] num = {1, 2, 3, 4, 5};
int[] tmp = new int[5];
System.arraycopy(num, 0, tmp, 0, 5);
int index = java.util.Arrays.binarySearch(tmp, 5); //搜索值为5的元素下标
boolean bn = java.util.Arrays.equals(num, tmp); //比较num和tmp是否相等
java.util.Arrays.fill(tmp, 123); //将tmp中的所有元素都填充为123
String ss = java.util.Arrays.toString(tmp); //将tmp中的所有元素转为String,并以逗号分割,放在中括号中
总结
Java 编程语言同时使用“字段”和“变量”作为其术语的一部分。实例变量(非静态字段)对于类的每个实例都是唯一的。类变量(静态字段)是用static修饰符声明的字段;无论类被实例化多少次,类变量都只有一个副本。方法中的变量是局部变量。参数是为方法提供额外信息的变量;局部变量和参数总是被归类为“变量”(而不是“字段”)。
参考资料:Java8官方教程