变量
为什么需要变量
一花一世界,如果把一个程序看做一个世界或一个社会的话,那么变量就是程 序世界的花花草草、万事万物。即,变量是程序中不可或缺的组成单位,最基 本的存储单元。
初识变量
变量的概念
-
内存中的一个存储区域,该区域的数据可以在同一类型范围内不断变化
-
变量的构成包含三个要素:数据类型、变量名、存储的值
-
Java 中变量声明的格式:数据类型 变量名 = 变量值
变量的作用
用于在内存中保存数据。
使用变量注意
-
Java 中每个变量必须先声明,后使用。
-
使用变量名来访问这块区域的数据。
-
变量的作用域:其定义所在的一对{ }内。
-
变量只有在其作用域内才有效。出了作用域,变量不可以再被调用。
-
同一个作用域内,不能定义重名的变量。
Java 中变量的数据类型
Java 中变量的数据类型分为两大类
-
基本数据类型:包括 整数类型(byte, short, int, long)、浮点数类型(float, double)、字符类型(char)、布尔类型(boolean)
-
引用数据类型:包括数组(array)、 类(class)、接口(interface)、枚举(enum)、注解(annotation)、记录(record)。
变量的使用
变量的声明
格式:数据类型 变量名;
注意:变量的数据类型可以是基本数据类型,也可以是引用数据类型。
//例如: //存储一个整数类型的年龄 int age;
//存储一个小数类型的体重 double weight;
//存储一个单字符类型的性别 char gender;
//存储一个布尔类型的婚姻状态 boolean marry;
//存储一个字符串类型的姓名 String name;
//声明多个同类型的变量
int a,b,c; //表示 a,b,c 三个变量都是 int 类型。
变量的赋值
给变量赋值,就是把“值”存到该变量代表的内存空间中。同时,给变量赋的值 类型必须与变量声明的类型一致或兼容。
变量赋值的语法格式: 变量名 = 值;
举例 1:可以使用合适类型的常量值给已经声明的变量赋值举例
age = 18;
weight = 109;
gender = '女';
举例 2:可以使用其他变量或者表达式给变量赋值
int m = 1; int n = m;
int x = 1;
int y = 2;
int z = 2 * x + y;
举例 3:变量可以反复赋值
//先声明,后初始化
char gender;
gender = '女';
//给变量重新赋值,修改 gender 变量的值
gender = '男';
System.out.println("gender = " + gender); //gender = 男
举例 4:也可以将变量的声明和赋值一并执行
boolean isBeauty = true;
String name = "迪丽热巴";
变量内存结构如图
基本数据类型
基本数据类型范围
整数类型(byte、short、int、long)
Java 各整数类型有固定的表数范围和字段长度,不受具体操作系统的影响,以保证 Java 程序的可移植性。
-
定义 long 类型的变量,赋值时需要以"l"或"L"作为后缀。
-
Java 程序中变量通常声明为 int 型,除非不足以表示较大的数,才使用 long。
-
Java 的整型常量默认为 int 型。
浮点类型(float、double)
与整数类型类似,Java 浮点类型也有固定的表数范围和字段长度,不受具体操作系统的 影响。
浮点型常量有两种表示形式:
十进制数形式。如:5.12 512.0f .512 (必须有小数点)
科学计数法形式。如:5.12e2 512E2 100E-2
float:单精度,尾数可以精确到 7 位有效数字。很多情况下,精度很难满足需求。定义 float 类型的变量,赋值时需要以"f"或"F"作为后缀。
double:双精度,精度是 float 的两倍。通常采用此类型。
Java 的浮点型常量默认为double型。
关于浮点型精度的说明
并不是所有的小数都能可以精确的用二进制浮点数表示。二进制浮点数不能精确的表 示 0.1、0.01、0.001 这样 10 的负次幂。
浮点类型 float、double 的数据不适合在不容许舍入误差的金融计算领域。如果需要 精确数字计算或保留指定位数的精度,需要使用 BigDecimal 类。
//测试 1:(解释见章末企业真题:为什么 0.1 + 0.2 不等于 0.3)
System.out.println(0.1 + 0.2);//0.30000000000000004
//测试 2:
float ff1 = 123123123f;
float ff2 = ff1 + 1;
System.out.println(ff1);
System.out.println(ff2);
System.out.println(ff1 == ff2); // true, 是因为浮点类型 float、double 精度不高
// 测试3: 定义圆周率并赋值为 3.14,现有 3 个圆的半径分别为 1.2、2.5、6,求
它们的面积。
public class Exercise1 {
public static void main(String[] args) {
double PI = 3.14; //圆周率
double radius1 = 1.2;
double radius2 = 2.5;
int radius3 = 6;
System.out.println("第 1 个圆的面积:" + PI * radius1 * radius1);
System.out.println("第 2 个圆的面积:" + PI * radius2 * radius2);
System.out.println("第 3 个圆的面积:" + PI * radius3 * radius3);
}
}
字符类型(char)
char 型数据用来表示通常意义上“字符”(占 2 字节)
Java 中的所有字符都使用 Unicode 编码,故一个字符可以存储一个字母,一个汉字,或 其他书面语的一个字符。
字符型变量的三种表现形式:
形式 1:使用单引号(' ')括起来的单个字符。 例如:char c1 = 'a'; char c2 = '中'; char c3 = '9';
形式 2:直接使用 Unicode 值来表示字符型常量:‘\uXXXX’。其中, XXXX 代表一个十六进制整数。
例如:\u0023 表示 '#'。
形式 3:Java 中还允许使用转义字符‘\’来将其后的字符转变为特殊字符 型常量。例如:char c3 = '\n'; // '\n'表示换行符
char 类型是可以进行运算的。因为它都对应有 Unicode 码,可以看做是一个数值。
转义字符 | 说明 | Unicode表示方式 |
\n | 换行符 | \u000a |
\t | 制表符 | \u0009 |
\" | 双引号 | \u0022 |
\' | 单引号 | \u0027 |
\\ | 反斜线 | \u005c |
\b | 退格符 | \u0008 |
\r | 回车符 | \u000d |
字符集
也叫编码表。是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图形符号、数字等
详细的参考: 关于字符集
char c = 97;
System.out.println(c) // a
布尔类型(boolean)
boolean 类型用来判断逻辑条件,一般用于流程控制语句中:
if 条件控制语句;
while 循环控制语句;
for 循环控制语句;
do-while 循环控制语句;
boolean 类型数据只有两个值:true、false,无其它值
不可以使用 0 或非 0 的整数替代 false 和 true,这点和 C 语言不同。
拓展:Java 虚拟机中没有任何供 boolean 值专用的字节码指令,Java 语言 表达所操作的 boolean 值,在编译之后都使用 java 虚拟机中的 int 数据类 型来代替:true 用 1 表示,false 用 0 表示。
boolean isFlag = true;
if(isFlag){
//true 分支
}else{
//false 分支
}
Less is More!建议不要这样写:if ( isFlag = = true ),只有新手才如 此。关键也很容易写错成 if(isFlag = true),这样就变成赋值 isFlag 为 true 而不是判断
!老鸟的写法是 if (isFlag)或者 if ( !isFlag)。
基本数据类型变量间运算规则
在 Java 程序中,不同的基本数据类型(只有 7 种,不包含 boolean 类型)变量 的值经常需要进行相互转换。
转换的方式有两种:自动类型提升和强制类型转换。
自动类型提升
规则:将取值范围小(或容量小)的类型自动提升为取值范围大(或容量大) 的类型 。
基本数据类型的转换规则如图所示:
当把存储范围小的值(常量值、变量的值、表达式计算的结果值)赋值给 了存储范围大的变量时
int i = 'A';//char 自动升级为 int,其实就是把字符的编码值赋值给 i 变量了
double d = 10; //int 自动升级为 double
long num = 1234567; //右边的整数常量值如果在 int 范围呢,编译和运行都可以通过,这里涉及到数据类型转换
// byte bigB = 130; //错误,右边的整数常量值超过 byte 范围
long bigNum = 12345678912L; //右边的整数常量值如果超过 int 范围,必须加 L, 显式表示 long 类型。否则编译不通过
当存储范围小的数据类型与存储范围大的数据类型变量一起混合运算时, 会按照其中最大的类型运算。
int i = 1; byte b = 1; double d = 1.0;
double sum = i + b + d;//混合运算,升级为 double
注意: 当 byte,short,char 数据类型的变量进行算术运算时,按照 int 类型处理。
byte b1 = 1;
byte b2 = 2;
byte b3 = b1 + b2; //编译报错,b1 + b2 自动升级为 int, 至少需要使用int来接收, 使用short也不行
char c1 = '0';
char c2 = 'A';
int i = c1 + c2; //至少需要使用 int 类型来接收
System.out.println(c1 + c2);//113
long s = 123; // 将int类型赋值给long类型, 自动类型提升
long a = 45243542345235; // 结果会报错, 45243542345235是int类型, 报错是因为超出了int范围, 所以报错
long c = 45243542345235L;
float f1 = 12.4f
float f2 = 12.3; // 12.3默认是double类型, 将double类型赋值给float类型, 不满足自动类型提升的规则, 所以结果会报错
强制类型转换
规则:将取值范围大(或容量大)的类型强制转换成取值范围小(或容量小) 的类型。
自动类型提升是 Java 自动执行的,而强制类型转换是自动类型提升的 逆运算,需要我们自己手动执行。
转换格式: 数据类型 1 变量名 = (数据类型 1)被强转数据值; //()中的数据类型必须<=变量值 的数据类型
将3.14 赋值到int 类型变量会发生什么?产生编译失败,肯定无法赋值。
int i = 3.14; // 编译报错
想要赋值成功,只有通过强制类型转换,将double 类型强制转换成int 类型才 能赋值。
1. 当把存储范围大的值(常量值、变量的值、表达式计算的结果值)强制转 换为存储范围小的变量时,可能会损失精度或溢出。
int i = (int)3.14; //损失精度, 结果是3 , 截断操作, 不是四舍五入
double d = 1.2;
int num = (int)d; //损失精度
int i = 200;
byte b = (byte)i; //溢出, 200超出了byte的范围
2. 当某个值想要提升数据类型时,也可以使用强制类型转换。这种情况的强制类型转换是没有风险的,通常省略。
int i = 1;
int j = 2;
double bigger = (double)(i/j);
声明 long 类型变量时,可以出现省略后缀的情况。float 则不同。
long l1 = 123L;
longl2=123;//如何理解呢? 此时可以看做是int类型的123自动类型提升为l ong 类型
//long l3 = 123123123123; //报错,因为 123123123123 超出了 int 的范围。 long l4 = 123123123123L;
//float f1 = 12.3; //报错,因为 12.3 看做是 double,不能自动转换为 float 类型
float f2 = 12.3F;
float f3 = (float)12.3;
String与基本数据类型变量间的运算
详细查看: Java基础 引用数据类型String(字符串)