目录:
1、数据类型
2、变量
3、数组
1.数据类型
谈到java的数据类型,必须知道java是强类型语言。首先,每个变量有类型,每个表达式有类型,而且每种类型是严格定义的。其次,所有的数值传递,不管是直接的还是通过方法调用经由参数传过去的都要先进行类型相容性的检查。有些语言没有自动强迫进行数据类型相容性的检查或对冲突的类型进行转换的机制。但是Java编译器会对所有的表达式和参数进行类型相容性的检查以保证类型是兼容的。任何类型的不匹配都是错误的,在编译器完成编译以前,错误必须被改正。
java中的简单数据类型有8个,代表简单数值,而不是一个对象。同时这些简单类型在任何平台运行java程序时,都是固定位数,体现了java的可移植性。分别是以下八个,分为三大类:
整数类型:采用补码的形式在内存中存储。
字节型(byte),占8位,范围:–28~28-1,常用于网络或文件处理数据流。
短整型(short),占16位,范围:–216~216-1,基本不用。
整形(int),占32位,范围:–232~ 232-1,常用在各种程序中间变量,类属性等。
长整型(long),占64位,范围:–264 ~ 264-1,用于特殊数值比较大的时候。
浮点类型:
浮点型(float),占32位,范围:3.4-38~3.4+38(注意float范围大于long)
双精度浮点型(double),占64位,范围:1.7-308~1.7+308
字符型(char),占16位,范围:0~217-1。每一个值都对应着一个字符,涵括了世界上所有的字符。尽管char是字符,但是本质上还是以整数位标记,因此可以对其进行类似于数值的操作。
布尔型(boolean),占1位,范围:true、false。
字面量
字面量,意思就是一个值,比如23、19.8、a、false等。
首先整数字面量最好理解,他们都是基于十进制的值。如果要使用8进制,则在数值前面加上导0,比如023代表19。但是08将会没有意义,因为八进制中没有8。如果要使用16进制,则在数值前面加上0x或0X。整数字面量在java中是默认按照int进行处理,即在内存中占用32位。可以通过在字面量后面加上l或者L来指定这是一个long型字面量。int型字面量赋值给long或者int当然没有问题,但是赋值给byte或者short时,就要考虑是否越界。将int字面量赋值给byte时,会先对256取余,再将余数赋值给byte。显然当字面量小于256可以正常赋值,但是大于256时,会出现错误。
浮点型字面量可以用3.44或者2.933e1(科学计数法)来表示。浮点型字面量默认是64位的double型,通过在字面量后面加上f或者F可以指定float型字面量。
布尔型字面量最简单,只有false或者true。注意0或者1不是布尔型字面量,他们只能被赋给已定义的布尔变量,或在布尔的运算符表达式中使用。
对于字符型字面量,由于java采用Unicode码表示字符,可以对其进行类似整数的运算。一般用‘xxx’来表示xxx字符的字面量。对于一些不能被直接包括的字面量,有一些转义符可以使用。
字符串字面量,比如“this is a string”,用“”括起来。注意之前的c或者c++都是讲字符串当做是字符的数组进行处理,java中不同,是当做一个对象来处理的。因此就有很多专用于java字符串处理的类与对应的方法。常见的String,StringBuilder,StringBuffer(线程安全的StringBuilder)。
2.变量
典型定义变量的表达式:type identifier [ = value][,identifier [= value] ...] ;其中,type是变量类型,identifier是变量标识符,[]内可以省略,可选是否初始化以及同时定义多个同类型变量。同时定义变量时也支持动态初始化,只要表达式是有效的。比如说:
double c = Math.sqrt(a * a + b * b);
变量的作用域与生存期
Java中,有程序块的概念。首先,程序块是指两个{}之间的代码块,代码块创建后也就产生了一个作用域。一般的程序语言都有局部变量以及全局变量的概念。Java中变量作用域主要取决于类与方法(类似于程序块)。类暂不讨论,此处先讨论方法中变量的作用域。方法中定义的变量,只能在整个方法中使用,对外界不可见。方法中又嵌套程序块时,程序块内的变量对块外不可见。同时,同一方法内,程序块内与程序块外变量不可同名。
变量在被定义后才是合法,可以使用的,也就是在内存中开辟了一块空间给变量。同时,当变量所在的程序块或者方法执行完毕后,变量也随之销毁,开辟的内存空间也就被回收。因此变量的生命期就是从其开始被定义到其所在程序块运行结束。
类型转换、强制类型转换与自动转换
自动类型转换需要满足两个条件:1.这两种类型兼容(数值类型与char不兼容)2.目的类型数的范围大于源类型。当不满足自动转换时,便要进行强制类型转换,会出现两种情况:1.将int赋给byte,见上字面量中描述。2.将浮点赋给整型,此时会发生截断,即小数部分被舍弃,只有整数部分被赋给整型变量了。
byte b; int i = 257; double d = 323.142; b = (byte) i; System.out.println("i and b " + i + " " + b);//i and b 257 1 i = (int) d; System.out.println("d and i " + d + " " + i);//d and I 323.142 323 b = (byte) d; System.out.println("d and b " + d + " " + b);//d and b 323.142 67
自动类型提升发生在表达式的计算中,看如下代码:
short a=23; byte b=22,c=41; int I = b*c/a;
当分析表达式时,Java自动提升各个byte型或short型的操作数到int型。这意味着子表达式b*c使用整数而不是字节型来执行,尽管变量b和c都被指定为byte型,22*41中间表达式的结果是合法的。下面有一个特例:byte a=2;a = a*3;看起来没有发生越界,但实际上a*3已经是int类型数值,直接赋给byte型的a肯定不对,因此编译会报错,解决办法是:a=(byte)a*3;即加上强制类型转换。自动类型提升的约定:所有的byte跟short会默认提升到int;表达式有long就全部默认到long;表达式有float就默认全部到float;表达式有double就全部默认到double。即:byte/short->int->long->float->double。
3.数组
谈到Java中的数组,首先要分清其余C或者C++中数组的区别。Java中的数组是类似于对象的一种实物。比如说int[ ] A;看上去是定义了一个名为A的int型数组,但是在内存中编译器实际上还没有给该数组分配内存空间。只有int[ ] A = new int[10];这样,才在内存中开辟了10个int类型大小的存储空间给A数组。同时可以定义数组的时候就对其初始化,并用A[x]的形式访问数组第x+1个元素,这点类似于c语言。
一个注意点时,Java会严格检查我们是否访问或存储了数组范围以外的值。。Java的运行系统会检查以确保所有的数组下标都在正确的范围以内(在这方面,Java与C/C++从根本上不同,C/C++不提供运行边界检查)。
多维数组
多维数组可以理解为是数组的数组。比如说一个二维数组int[ ][ ] A= new int[3][4];就是定义了一个3个数组,每个数组含有4个元素。理解为3*4,即3行4列,每行是一个数组,有3个数组。
同时,多维数组允许我们指定每一个数组大小不同。比如int[ ][ ] A= new int[3][ ];然后分别对这三个数组指定大小;A[0] = new int[1]; A[1] = new int[2]; A[2] = new int[3];这样二维数组A的三个子数组A[0],A[1],A[2]大小分别为1,2,3,这样就定义了一个下三角矩阵。多维数组同样也可以定义的时候就初始化,比如说:int[ ][ ] A = new int{{1},{1,2},{1,2,3}};这样就给上面描述的下三角矩阵A数组初始化了。
TIPS:java为何不支持指针?
众所周知,c语言与C++全部都是支持指针操作的,即通过指针来直接访问计算设备中的内存。指针就是一个内存设备的地址,通过其可以直接读取或者修改该内存单元的值。而Java的特点就是通过在各种平台上实现JVM,然后在JVM提供的运行环境下运行Java程序。如果说提供指针来直接访问各种平台的内存,那么程序的运行将会脱离JVM的控制,这样由JVM提供的跨平台移植性,安全性均无法得到保证。但也无需担心丢失了指针特性会对我们写Java程序有多大的影响,只要是在JVM的运行环境下,我们就不需要使用指针,使用指针也不会带来任何好处。