变量
关键字
- 定义数据(12个): c l a s s {\color{red}class} class i n t e r f a c e {\color{red}interface} interface e n u m {\color{red}enum} enum b y t e {\color{red}byte} byte s h o r t {\color{red}short} short i n t {\color{red}int} int l o n g {\color{red}long} long f l o a t {\color{red}float} float d o u b l e {\color{red}double} double c h a r {\color{red}char} char b o o l e a n {\color{red}boolean} boolean v o i d {\color{red}void} void
- 流程控制(11个): i f {\color{red}if} if e l s e {\color{red}else} else s w i t c h {\color{red}switch} switch c a s e {\color{red}case} case d e f a u l t {\color{red}default} default w h i l e {\color{red}while} while d o {\color{red}do} do f o r {\color{red}for} for b r e a k {\color{red}break} break c h a r {\color{red}char} char c o n t i n u e {\color{red}continue} continue
- 权限修饰(3个): p r i v a t e {\color{red}private} private p r o t e c t e d {\color{red}protected} protected p u b l i c {\color{red}public} public
- 修饰类,函数,变量(4个): a b s t r a c t {\color{red}abstract} abstract f i n a l {\color{red}final} final s t a t i c {\color{red}static} static s y n c h r o n i z e d {\color{red}synchronized} synchronized
- 类与类之间: e x t e n d s {\color{red}extends} extends i m p l e m e n t s {\color{red}implements} implements
- 实例(4个): n e w {\color{red}new} new t h i s {\color{red}this} this s u p e r {\color{red}super} super i n s t a n c e o f {\color{red}instanceof} instanceof
- 异常处理(5个): t r y {\color{red}try} try c a t c h {\color{red}catch} catch f i n a l l y {\color{red}finally} finally t h r o w {\color{red}throw} throw t h r o w s {\color{red}throws} throws
- 包: p a c k a g e {\color{red}package} package i m p o r t {\color{red}import} import
- 其他关键字(7个): n a t i v e {\color{red}native} native s t r i c t f p {\color{red}strictfp} strictfp t r a n s i e n t {\color{red}transient} transient v o l a t i l e {\color{red}volatile} volatile a s s e r t {\color{red}assert} assert c o n s t {\color{green}const} const g o t e {\color{green}gote} gote
- 字面值: t r u e {\color{black}true} true f a l s e {\color{black}false} false n u l l {\color{black}null} null
关键字全部为小写字母
字面值不是关键字,但不能作为变量使用
标识符
什么是标识符?
Java中变量、方法、类等要素命名时使用的字符序列,称为标识符。
用于类名、方法名、变量名、包名、常量名等。
标识符的命名规则
- 由26个英文字母的大小写,0-9,_或$组成
- 数字不可以开头
- 不可以使用关键字和保留字,但是可以包含关键字和保留字
- Java严格区分大小写,长度无限制
- 标识符不能包含空格
标识符的命名规范
- 包名:多单词组成时所有字母小写:xxxyyyzzz
- 类名、接口名:多单词组成时,所有单词首字母大写:XxxYyyZzz
- 变量名、方法名:多单词组成时,第一个单词全部小写,从第二个单词开始,每个单词首字母大写:xxxYyyZzz
- 常量名:多单词组成时,所有字母大写,单词之间使用_连接
定义标识符(起名字)需要做到见名知意。
class IdentifierTest
{
public static void main(String [] args){
int abc = 12;
int age = 25; //age:标识符
char gender = '男';
}
public static void main1(String [] args){
}
}
变量
变量是程序中不可或缺的组成单位,是最基本的存储单元。
初识变量
-
变量的概念:
-
内存中的一个存储区域,该区域的数据可以在同一类型范围内不断变化
-
变量的构成包含三个要素:
数据类型
、变量名
、存储的值
-
Java中变量声明的格式:
数据类型 变量名 = 变量值
-
-
变量的作用:用于在内存中保存数据。
-
使用变量注意:
- Java中变量必须先声明,后使用。
- 定义好变量后,可以使用变量名对变量进行调用和运算。
- 变量的作用域:其定义所在的一对{ }内。
- 变量只有在其
作用域
内才有效。出了作用域,变量不可以再被调用。 - 在同一个作用域内,不能声明两个同名的变量。
class VariableTest
{
public static void main(String[] args)
{
char gender; // 变量的声明
// 在同一个作用域不能声明两个同名的变量
gender = '男';// 变量的赋值
gender = '女';// 重新赋值
int age = 10; // 定义变量,二者合一
// System.out.println("Hello World!");
System.out.println(age);
System.out.println("age = " + age);
System.out.println("gender = " + gender);
}
public static void main1(String[] args)
{
char gender = '女';
}
}
Java的数据类型
Java中数据类型分为两大类:
-
基本数据类型:包括
整数类型(int)
、浮点数类型(float)
、字符类型(char)
、布尔类型boolean
。 -
引用数据类型:包括
数组(array)
、类(class)
、接口(interface)
、枚举(enum)
、注解(anotation)
、记录(record)
。
变量的使用
声明
数据类型 变量名; //每行结尾需要以;结尾
数据类型 变量名1, 变量名2, 变量名3; //每行结尾需要以;结尾
变量的赋值
变量名 = 值;
变量名 = 已赋值的变量名;
变量名 = 表达式;
age = 18;
weight = 109;
gender = '女';
int a = 1;
int b = a;
int x = 1;
int y = 2;
int z = 2 * x + y;
//重复赋值
x = 2;
x = 3;
gender = '男';
声明+赋值
String name = "周华健";
基本数据类型
基本数据类型
Java的基本数据类型有8种,它们分别是:
-
byte:字节型,占1个字节(8位),取值范围从-128到127。
-
short:短整型,占2个字节(16位),取值范围从-32,768到32,767。
-
int:整型,占4个字节(32位),取值范围从-2,147,483,648到2,147,483,647。这是Java中最常用的整数类型。
-
long:长整型,占8个字节(64位),取值范围从-9,223,372,036,854,775,808到9,223,372,036,854,775,807。长整型数值后面通常带上一个
L
表示。 -
float:浮点型,占4个字节(32位),取值范围大约从1.4E-45到3.4028235E38。float类型的数值后面通常加上一个
f
。 -
double:双精度浮点型,占8个字节(64位),取值范围大约从4.9E-324到1.7976931348623157E308。double是Java默认的浮点数类型,因此,在声明浮点数时,如果不指定
f
,则默认为double类型。 -
char:字符型,占2个字节(16位),表示Unicode字符,取值范围从’\u0000’(即为0)到’\uffff’(即为65,535)。
-
boolean:布尔型,用于表示逻辑值,它只有两个取值:true和false。
这些基本数据类型是Java语言的核心,是构建所有Java程序的基础。在Java中,所有的对象都不是基本数据类型,而是通过类(Class)来实现的,这包括像字符串(String)这样的复合数据类型。
基本数据类型与对象类型(例如封装类)的一个重要区别是,基本数据类型直接存储值,而对象类型存储的是对象的引用。
基本数据类型在内存中是如何存储的?
在Java中,基本数据类型变量的值是
直接存储在栈内存
(Stack Memory)中的。每个线程都有自己的栈,用于存储局部变量和方法调用的上下文信息。基本数据类型的变量在栈上分配空间,并且它们的值是直接存储在这个空间中的。
以下是基本数据类型在内存中的存储方式:
- byte、short、int、long、float、double:这些数值类型的数据直接存储在栈上。例如,声明一个
int
变量时,会在栈上分配4个字节的空间来存储该变量的值。- char:字符类型也是数值类型,它存储的是字符的Unicode码点值。
char
类型的变量同样直接在栈上分配2个字节的空间。- boolean:布尔类型比较特殊,它只有两个值:true和false。在Java内部,布尔值可能被存储为1字节的数值(true为1,false为0),但是这种存储方式依赖于具体的Java虚拟机实现,并不是Java语言规范的一部分。从概念上来说,布尔值仍然是在栈上分配的。
需要注意的是,
- Java中的对象(包括封装了基本数据类型的对象,如Integer、Float等)是存储在堆内存(Heap Memory)中的。堆内存是所有线程共享的,用于存储创建的对象和数组。
- 当基本数据类型的值被封装成对象时(例如通过自动装箱),这些对象就会存储在堆上,并且栈上的变量将存储对这些对象的引用。
- 此外,Java的垃圾回收器(Garbage Collector)会定期清理堆内存中不再使用的对象,以释放内存空间。而栈内存的管理是自动的,由线程的栈帧(Stack Frame)的创建和销毁来管理,不需要垃圾回收器的介入。
浮点数精度
-
并不是所有的小数都能可以精确的用二进制浮点数表示。二进制浮点数不能精确的表示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类型。
练习
class FloatDoubleExer
{
public static void main(String[] args)
{
// 定义圆周率
double pi = 3.14;
// 定义3个半径
double redius1 = 1.2;
double redius2 = 3.5;
int redius3 = 6;
// 计算3个圆的面积
double area1 = pi * redius1 * redius1;
double area2 = pi * redius2 * redius2;
double area3 = pi * redius3 * redius3;
// 输出
System.out.println("半径为" + redius1 + "的圆的面积是" + area1);
System.out.println("半径为" + redius2 + "的圆的面积是" + area2);
System.out.println("半径为" + redius3 + "的圆的面积是" + area3);
}
}
字符类型
class CharTest
{
public static void main(String[] args)
{
// 字符类型:char(2字节)
// 表示形式1:使用'',内部有且仅有一个字符Unicode编码
char c1 = 'a';
char c2 = '中';
char c3 = '1';
char c4 = '%';
char c5 = 'γ';
// 表示形式2:直接使用Unicode值表示字符型常量:\\uxxxx
char c6 = '\u0023';
System.out.println(c6);
// 表示形式3:使用转义字符
char c7 = '\n';
char c8 = '\t';
// 表示形式4:使用ASCII编码值
char c9 = 97;
System.out.println(c9); // a
}
}
转义字符 | 说明 | Unicode表示方式 |
---|---|---|
\n | 换行符 | \u000a |
\t | 制表符 | \u0009 |
\" | 双引号 | \u0022 |
\' | 单引号 | \u0027 |
\\ | 反斜线 | \u005c |
\b | 退格符 | \u0008 |
\r | 回车符 | \u000d |
布尔类型
class BooleanTest
{
public static void main(String[] args)
{
// 布尔类型
// 只有两个取值:true \ false
boolean bo1 = true;
boolean bo2 = false;
// 编译不通过
// boolean bo3 = 0;
// 布尔值经常使用在判断结构和循环结构中
boolean isRain = false;
if (isRain)
{
System.out.println("需要打伞");
} else
{
System.out.println("不需要打伞");
}
}
}
基本数据类型的运算
自动数据类型提升
- 可以做运算的基本数据类型有7种,不包含boolean类型。
- 运算规则包括:
- 自动类型转换
- 强制类型转换
// 测试自动类型提升
class VariableTest
{
public static void main(String[] args)
{
// 自动类型提升的规则:当容量小的变量和容量大的变量做运算时,结果自动转换为容量大的数据类型
// 容量的大小不是指数据类型占用的字节大小,而是所表示数据的范围大小
int i1 = 10;
int i2 = i1;
long l1 = i1;
float f1 = l1;
double d1 = f1;
// 可以看到数据类型在 int -> long -> float -> double 的顺序下可以做到自动提升
byte b1 = 12;
int i3 = b1 + i1;
//编译不通过
//byte b2 = b1 + i1;
//特殊的情况1:
byte b3 = 12;
byte b4 = 13;
short s1 = 10;
short s2 = 12;
//short s2 = b3 + s1; //编译不通过 byte + short 应该用int接收
int i4 = b3 + s1;
//byte b5 = b3 + b4; //编译不通过 byte + byte 应该用int接收
//short s3 = s1 + s2; //编译不通过 short + short 应该用int接收
//特殊的情况2:
char c1 = 'a';
//char c2 = c1 + b1; //编译不通过 char + byte 应该用int接收
//char c3 = c1 + s1; //编译不通过 char + short 应该用int接收
//练习1:
long l2 = 123L;
long l3 = 123; //int --> long 属于自动类型提升
//long l4 = 132123123123; //编译不通过,132123123123超出了int所能表示的范围
long l5 = 132123123123L;
//练习2:
float f2 = 12.3F;
//float f3 = 12.3; //编译不通过,浮点数不加F后缀默认为double类型,double -\-> float
//练习3:
//规定1:浮点数默认为double类型
//规定2:整数默认为int类型
//byte b5 = b1 + 1; //编译不通过 byte + 整数常量 应该用int接收
//short s4 = s1 + 1; //编译不通过 short + 整数常量 应该用int接收
double d2 = b1 + 12.3;//浮点数默认为double类型
//练习4:
//为什么变量名不能以数字开头?
//int 123L = 123;
//double l6 = 123L; //这里无法说明123L是常量还是变量
}
}
强制类型转换
- 如果需要将大容量数据类型转换为小容量数据类型,需要使用强制类型转换
- 强制类型转换需要使用强转符: (). 在()内指明要转换的数据类型
- 强制类型转换可能造成精度损失
class VariableTest
{
public static void main(String[] args)
{
//测试强制类型转换
double d1 = 12.3;
int i1 = (int)d1;
System.out.println("i1 = " + i1); //精度损失-->截断
int i = (int)3.14;//损失精度
double d2 = 1.2;
int num = (int)d2;//损失精度
int i2 = 200;
byte b = (byte)i2;//溢出
long l1 = 123L;
short s1 = (short)l1;
System.out.println("l1 = " + l1);
}
}