变量指的是程序运行时可变的量. 相当于开辟一块内存空间来保存一些数据. 类型则是对变量的种类进行了划分, 不同的类型的变量具有不同的特性
输入设备 :键盘,文件
输出设备:屏幕,文件
内存储器:内存(RAM)
外存储器:硬盘,u盘,磁盘,光盘
运算器+控制器=cpu
首先来介绍下变量的命名规范
硬性指标:
1. 一个变量名只能包含数字, 字母, 下划线
2. 数字不能开头.
3. 变量名是大小写敏感的. 即 num 和 Num 是两个不同的变量.
注意: 虽然语法上也允许使用中文/美元符($)命名变量, 但是 强烈 不推荐这样做.一般不以下划线,美元符号开头或者结尾,即合法不合理,即使编译是可以通过的
4:变量名不能与Java中的关键字重复。
软性指标:
1. 变量命名要具有描述性, 见名知意.
2. 变量名不宜使用拼音(但是不绝对).
3. 变量名的词性推荐使用名词.
4. 变量命名推荐 小驼峰命名法, 当一个变量名由多个单词构成的时候, 除了第一个单词之外, 其他单词首字母都大写.
小驼峰命名示例:
int maxValue = 100;
String studentName = "张三";
int 变量名=初始值;
int num = 10 ; // 定义一个整型变量System.out.println(num);
1.整形int为4个字节,不区分多少位机器,int整形变量为有符号数,所以既可以取正数也可以取负数,所以int的取值范围为-2147483648---2147483647(-2^31--->2^31-1).
至于为什么是2的31次方是因为int为4个字节,4个字节一共是32位,最高位为符号位为1,其余31为都是数值位,所以是2的31次方。
在这里顺便介绍下字节:字节是计算机中表示空间大小的基本单位. 计算机使用二进制表示数据. 我们认为 8 个二进制位(bit) 为一个字节(Byte). 我们平时的计算机为 8GB 内存, 意思是 8G 个字节. 其中 1KB = 1024 Byte, 1MB = 1024 KB, 1GB = 1024 MB. 所以 8GB 相当于 80 多亿个字节.
使用以下代码查看 Java 中的整型数据范围:
System.out.println(Integer.MAX_VALUE); // int 的最大值
System.out.println(Integer.MIN_VALUE); // int 的最小值
如果运算的结果超出了 int 的最大范围, 就会出现溢出的情况:分析下面两端代码最终的输出结果
System.out.println(Integer.MAX_VALUE+1)
分析:结果为-2147483648,因为加1后相当于一个圆回到了取值范围的最小值,系统在进行编译时并不知道MAX_VALUE的具体值是多少,只有程序运行的时候才知道,所以当MAX_VALUE加1时虽然明面上已经越界了,但是输出是没有问题的。
System.out.println(Integer.MIN_VALUE-1)分析:结果为2147483647,因为减1后相当于一个圆回到了取值范围的最大值,系统在进行编译时并不知道MIN_VALUE的具体值是多少,只有程序运行的时候才知道,所以当MAX_VALUE减1时虽然明面上已经越界了,但是输出是没有问题的。
2.java中int既可以表示正数,也可以表示负数,其不存在无符号数据类型。
3.int的包装类为Integer------int的plus版本
4.int在定义变量且赋值的时候,不能给一个超过其范围的数据,这题体现了java的安全性
int a=2147483648;此处代码会报错的原因是此时给a所赋的值超过了其取值范围,int的最大值为2147483647。
5.当变量在定义的时候没有初始化,则一定要在使用的时候初始化,否则便会编译错误。
int a;
System.out.println(a);
此处会报错,原因是a此时并没有被初始化就被使用,所以报错,更加体现出java的安全性。
思考:下面这段代码最终的输出结果为多少?
int e = Integer.MAX_VALUE;
e++;
e += 1;
System.out.println(e);
答:输出结果为-2147483647,首先e++后我们的e此时值为-2147483648,e+=1后此时变为了-2147483647.
21亿这样的数字对于当前的大数据时代来说, 是很容易超出的. 针对这种情况, 我们就需要使用更大范围的数据类型来表示了.,所以Java 中提供了 long
long 变量名 = 初始值;
long num = 10L; // 定义一个长整型变量, 初始值写作 10l 也可以(小写的 L, 不是数字1).
System.out.println(num);
1. 基本语法格式和创建 int 变量基本一致, 只是把类型修改成 long
2. 初始化设定的值为 10L , 表示一个长整型的数字. 10l 也可以,但是编译的时候会报错,运行的时候不会。
3. 使用 10 初始化也可以, 10 的类型是 int, 10L 的类型是 long, 使用 10 L 或者 10 l 更好一些.
4.Java 中 long 类型占 8 个字节. 表示的数据范围 -2^63 -> 2^63-1
5.long的包装类为Long
使用以下代码查看 Java 中的长整型数据范围:
System.out.println(Long.MAX_VALUE);
System.out.println(Long.MIN_VALUE);
运行结果为:
9223372036854775807
-9223372036854775808
这个数据范围远超过 int 的表示范围. 足够绝大部分的工程场景使用.
double 变量名 = 初始值;
double num = 1.0;
System.out.println(num);
1.double 占8个字节.
2.double的包装类为Double.
3.在真正的程序设计中没有精确的小数,他都是有精度的.(Java 的 double 类型的内存布局遵守 IEEE 754 标准(和C语言一样), 尝试使用有限的内存空间表示可能无限的小数, 势必会存在一定的精度误差.)
4.Java 中的 double 虽然也是 8 个字节, 但是浮点数的内存布局和整数差别很大, 不能单纯的用 2 ^ n 的形式来表示double数据范围.
java中int/int最后的结果仍然是一个int(会直接舍弃小数部分)
int a = 1;
int b = 2;
System.out.println(a / b);
// 执行结果
0
double c = 3.0, d = 8.0;
System.out.println(c / d);//输出结果为0.375
double e = 1.1;
System.out.println(e * e); //输出结果为1.2100000000000002,因为小数一般没有精确值,只有精度,所以结果为此值
System.out.printf("%.2f", e * e); //输出结果为小数点后两位,并用printf方法进行输出,输出结果为1.21.在这里顺便介绍println,printf,print三者的区别:
print与println的区别在于print不会换行,但是println会自动换行。
printf是格式化输出,与c语言用法类似。
float 变量名 = 初始值;
float num = 12.3f; // 写作 12.3F也可以
12.3默认是double类型,而此时将double类型不能赋给float类型, 因为double类型是八个字节,而float类型是四个字节,将八个字节赋给四个字节,会编译错误,体现了java的安全性,所以必须加上f,此外Java是一个强类型语言,C语言是一个弱类型语言, 这也是为什么将double类型赋值给float类型时c语言只会给出警告而java会编译错误的原因
System.out.println(num);
1.float占4个字节(float 类型在 Java 中占四个字节, 同样遵守 IEEE 754 标准. 由于表示的数据精度范围较小, 一般在工程上用到浮点数都优先考虑 double, 不太推荐使用 float.)
2.float的包装类为Float
char 变量名 = 初始值;
char ch = 'A';
1. Java 中使用 单引号 + 单个字母 的形式表示字符字面值.即在java中的字符类型常量必须被单引号所修饰,且单引号中只能放入单个字母,双引号表示的是字符串。
2. 计算机中的字符本质上是一个整数. 在 C 语言中使用 ASCII 表示字符, 而 Java 中使用 Unicode 表来表示字符. 因此一个字符占用两个字节, Unicode 表示的字符种类更多, 包括中文.取值范围为0-65535
3.char类型的包装类为Character
char ch = 'a';
System.out.println(ch);//输出结果为a
char ch1 = 97;
System.out.println(ch1);//输出结果为a,其找到的是97这个十进制数字在Unicode表中所对应的字符
char ch = '呵';
System.out.println(ch);//输出结果为呵,汉字为2个字节,与char所表示的字节数相同。
byte 变量名 = 初始值;
byte value = 0;
System.out.println(value);
System.out.println(Byte.MAX_VALUE); // byte 的最大值,输出结果为127
System.out.println(Byte.MIN_VALUE); // byte 的最小值,输出结果为-128
注意以下赋值会出错:
byte a=128;
因为此时我们a的赋值已经超过了byte的最大类型的取值范围127,所以会报错。
System.out.println(Byte.MAX_VALUE + 1); //输出结果为128,因为println的输出方法中默认是以整形进行打印的,而当MAX_VALUE等于127加1等于128,此时byte类型进行了整型提升变成了int类型,所以结果不再是-128,而是+128。
System.out.println(Byte.MIN_VALUE - 1); //因为println的输出方法中默认是以整形进行打印的,而当MAX_VALUE等于127加1等于128,此时byte类型进行了整型提升变成了int类型,所以结果不再是-128,而是-129。
代码1:
byte b=10;
byte c=20;
byte d=b+c;(错误)
//此句子会发生错误的原因是虽然b与c本身是byte,由于计算机的 CPU 通常是按照 4 个字节为单位从内存中读写数据.为了硬件上实现方便, 诸如 byte 和 short 这种低于 4 个字节的类型, 在进行算术运算时,会先提升成 int, 再参与计算.所以此时等式的右边是变成了int类型,而将int类型赋给byte类型的时候会报错
//若要使上式正确,则应该将等式右边进行强制类型转换或者将左边改成int类型,即如下两种方法:(1) byte d = (byte) (b + c);
(2) int d=b+c;
现在来分析下面这段代码,看是否会报错:
final byte b=10;
final byte c=20;
byte d=b+c; //因为final常量是在编译时期就确定的,所以byte d=b+c就等价于byte d=30,然后30并未超出byte的取值范围,故不会报错
二:代码2:
此处注意有两种情况不会进行整形的提升:
byte f = 127;
f++; //此f最后的单独输出结果为-128,并不会进行自动类型转换
f += 1; //此f最后的单独输出结果为-128,并不会进行自动类型转换,+=为复合运算符三:代码3:
byte d=Byte.MAX_VALUE+1;
此句的错误原因是由于计算机的 CPU 通常是按照 4 个字节为单位从内存中读写数据.为了硬件上实现方便, 诸如 byte 和 short 这种低于 4 个字节的类型, 在进行算术运算时,会先提升成 int, 再参与计算.所以此时等式的右边是变成了int类型,而将int类型赋给byte类型的时候会报错
1. 字节类型表示的也是整数. 只占一个字节, 表示范围较小 ( -128 -> +127 )(-2^7->+2^7-1)
2. 字节类型和字符类型互不相干.
3. byte的包装类为Byte
4.byte的整型提升
short 变量名 = 初始值;
short value = 0;
System.out.println(value);
1. short 占用 2 个字节, 表示的数据范围是 -32768 -> +32767(-2^15-2^15-1)
2. 这个表示范围比较小, 一般不推荐使用.
3.short的包装类为Short
System.out.println(Short.MAX_VALUE); // short 的最大值,输出结果为+32767
System.out.println(Short.MIN_VALUE); // short 的最小值,输出结果为-32768
System.out.println(Short.MAX_VALUE + 1); //输出结果为32768,因为println的输出方法中默认是以整形进行打印的,而当MAX_VALUE等于32767加1等于32768,此时short类型进行了整型提升变成了int类型,所以结果不再是-32768,而是+32768。
System.out.println(Short.MIN_VALUE - 1); //输出结果为-32769,因为println的输出方法中默认是以整形进行打印的,而当MAX_VALUE等于-32768减1等于-32769,此时short类型进行了整型提升变成了int类型,所以结果不再是+32767,而是-32769。
short e=Short.MAX_VALUE+1; //此句子会发生错误的原因是由于计算机的 CPU 通常是按照 4 个字节为单位从内存中读写数据.为了硬件上实现方便, 诸如 byte 和 short 这种低于 4 个字节的类型, 在进行算术运算时,会先提升成 int, 再参与计算.所以此时等式的右边是变成了int类型,而将int类型赋给short类型的时候会报错
boolean 变量名 = 初始值;
boolean value = true;
System.out.println(value);
1. boolean 类型的变量只有两种取值, true 表示真, false 表示假.
2. Java 的 boolean 类型和 int 不能相互转换, 不存在 1 表示 true, 0 表示 false 这样的用法.
3. boolean 类型有些 JVM 的实现是占 1 个字节, 有些是占 1 个比特位, 这个没有明确规定.即没有固定的大小.
4.boolean的包装类为Boolean
String 变量名 = "初始值";
String name = "zhangsan";
System.out.println(name);
1. Java 使用 双引号 + 若干字符 的方式表示字符串字面值.注意与char类型的不同之处。
2. 和上面的类型不同, String 不是基本类型, 而是引用类型(后面会有专门的博客重点解释).
3. 字符串中的一些特定的不太方便直接表示的字符需要进行转义.
// 创建一个字符串 My name is "张三"
String name = "My name is \"张三\"";
转义字符举例:现在输出"helloworld"该怎么输出呢?
String ch1="\"helloworld\""; //转义字符\
System.out.println(ch1); //输出结果为"helloworld"
String a = "hello";
String b = "world";
String c = a + b;
System.out.println(c);
还可以用字符串和整数进行拼接:
String str = "result = ";
int a = 10;
int b = 20;
String result = str + a + b;
System.out.println(result);
// 执行结果
result = 1020
以上代码说明, 当一个 + 表达式中存在字符串的时候, 都是执行字符串拼接行为. 因此我们可以很方便的使用 System.out.println 同时打印多个字符串或数字
int a = 10;
int b = 20;
System.out.println("a = " + a + ",b = " + b)
上面讨论的都是各种规则的变量, 每种类型的变量也对应着一种相同类型的常量. 常量指的是运行时类型不能发生改变.
常量主要有以下两种体现形式:
10 // int 字面值常量(十进制)
010 // int 字面值常量(八进制) 由数字 0 开头. 010 也就是十进制的 8
0x10 // int 字面值常量(十六进制) 由数字 0x 开头. 0x10 也就是十进制的 16
10L // long 字面值常量. 也可以写作 10l (小写的L)
1.0 // double 字面值常量. 也可以写作 1.0d 或者 1.0D
1.5e2 // double 字面值常量. 科学计数法表示. 相当于 1.5 * 10^2
1.0f // float 字面值常量, 也可以写作 1.0F
true // boolen 字面值常量, 同样的还有 false
'a' // char 字面值常量, 单引号中只能有一个字符
"abc" // String 字面值常量, 双引号中可以有多个字符.
final int a = 10;
a = 20; // 常量不能在程序运行过程中发生修改.否则会编译运行出错。
finnal int a;
System.out.println(a);
// 编译出错. 因为final定义的常量只能初始化一次,所以使用的时候,一定要记得初始化,否则会编译运行出错。
Java 作为一个强类型编程语言, 当不同类型之间的变量相互赋值的时候, 会有教严格的校验.
先看以下几个代码场景:
int a = 10;
long b = 20;
a = b; // 编译出错, 提示可能会损失精度.
b = a; // 编译通过.此处发生了隐形类型转换,即把一个小类型数据(字节数小)给大类型数据(字节数大)
int a = 10;
double b = 1.0;
a = b; // 编译出错, 提示可能会损失精度.
b = a; // 编译通过.此处发生了隐形类型转换,即把一个小类型数据(字节数小)给大类型数据(字节数大)
long 表示的范围更大, 可以将 int 赋值给 long, 但是不能将 long 赋值给 int.
double 表示的范围更大, 可以将 int 赋值给 double, 但是不能将 double 赋值给 int.
结论: 不同数字类型的变量之间赋值, 表示范围更小的类型能隐式转换成范围较大的类型, 反之则不行.
int a = 10;
boolean b = true;
b = a; // 编译出错, 提示不兼容的类型
a = b; // 编译出错, 提示不兼容的类型
结论: int 和 boolean 是毫不相干的两种类型, 不能相互赋值.
byte a = 100; // 编译通过
byte b = 256; // 编译报错, 因为byte的取值范围为-128-127,但是128此时已经超出范围了,为整形,将一个int类型数据赋给byte类型数据会报错.
注意: byte 表示的数据范围是 -128 -> +127, 256 已经超过范围, 而 100 还在范围之内.
结论: 使用字面值常量赋值的时候, Java 会自动进行一些检查校验, 判定赋值是否合理.
int a = 0;
double b = 10.5;
a = (int)b;//编译通过
int a = 10;
boolean b = false;
b = (boolean)a; // 编译出错, 提示不兼容的类型.
结论: 使用 (类型) 的方式可以将 double 类型强制转成 int. 但是
1. 强制类型转换可能会导致精度丢失. 如刚才的例子中, 赋值之后, 10.5 就变成 10 了, 小数点后面的部分被忽略.
2. 强制类型转换不是一定能成功, 互不相干的类型之间无法强转(例如boolean类型与int类型),事实上boolean类型不能跟任何基本数据类型进行强转.
1. 不同数字类型的变量之间赋值, 表示范围更小的类型能隐式转换成范围较大的类型.
2. 如果需要把范围大的类型赋值给范围小的, 需要强制类型转换, 但是可能精度丢失.
3. 将一个字面值常量进行赋值的时候, Java 会自动针对数字范围进行检查.
int a = 10;
long b = 20;
int c = a + b; // 编译出错, 当一个int类型(4个字节)和long(8个字节)进行算数运算时,小字节会自动提升为大字节,则int会自动提升为long类型,此时等式右边为long类型,左边为int类型,将一个long类型赋给int类型会发生编译错误
long d = a + b; // 编译通过.
结论: 当 int 和 long 混合运算的时候, int 会提升成 long, 得到的结果仍然是 long 类型, 需要使用 long 类型的变量来 接收结果. 如果非要用 int 来接收结果, 就需要使用强制类型转换.
运算1:
byte a = 10;
byte b = 20;
byte c = a + b;
System.out.println(c);
// 编译报错 Test.java:5: 错误: 不兼容的类型: 从int转换到byte可能会有损失 byte c = a + b;
结论:
byte 和 byte 都是相同类型, 但是出现编译报错. 原因是, 虽然 a 和 b 都是 byte, 但是计算 a + b 会先将 a 和 b 都 提升成 int, 再进行计算, 得到的结果也是 int, 这是赋给 c, 就会出现上述错误.
由于计算机的 CPU 通常是按照 4 个字节为单位从内存中读写数据. 为了硬件上实现方便, 诸如 byte 和 short 这种低于 4 个字节的类型, 会先提升成 int, 再参与计算.
一:byte a = 10;
byte b = 20;
byte c = (byte)(a + b);
System.out.println(c);
二:
byte a = 10;
byte b = 20;
int c = a + b;
System.out.println(c);
运算2:
byte a=10;
byte b=20;
a=a+b;//此处会编译报错
a+=b;//此处不会报错
System.out.println(a);
//输出结果为30
结论:a+=b的原因是+=这个复合运算符会自动进行隐式类型转换,所以最终a的输出值为30.
1. 不同类型的数据混合运算, 范围小的会提升成范围大的.
2. 对于 short, byte 这种比 4 个字节小的类型, 会先提升成 4 个字节的 int , 再运算.
int num = 10;
// 方法1
String str1 = num + ""; //可为一个数字加上一个空的字符串,这样这个数字最后变成了字符串
// 方法2
String str2 = String.valueOf(num);//用valueOf方法将一个int类型转变成为String类型
String str = "100";
int num = Integer.parseInt(str);//用parseInt方法将字符串参数解析为带符号的十进制整数
注意:此处的字符串参数只能是十进制整数的字符串。
因为Integer.parseInt方法其实默认是调用了
int i =Integer.parseInt("123",10)
10代表的默认是10进制的.
如果不是十进制整数字符串,会报java.lang.NumberFormatException错误。