从零开始的java语言学习第二天java程序内容的认识
在第一天的认识过程中我们已经知道了什么是java并且已经成功的创建了属于我们的第一个java文件,接下来我们从最基础的开始学习,开始第二天的java学习。
关键字
在 Java 中,关键字(Keywords) 是被编程语言预先定义的、具有特殊含义的保留字,你不能将它们用作变量名、方法名或类名等标识符。
我们把 Java 关键字想象成 建造一座精致小木屋(你的程序)所需的特殊工具和蓝图符号,借此我们开始java关键字的学习。
要注意的是关键字异常之多,可以在通过https://docs.oracle.com/javase/tutorial/java/nutsandbolts/_keywords.html这个网址查询关键字。
基础语法关键字
-
数据类型与变量
-
int
、double
、char
、boolean
:基本数据类型int:整块砖头(整数)。
double:更精细的沙子或水泥(带小数点的数)。
char
:单个字母或符号(如门牌号上的字母 'A')。
boolean:开关(
true
开灯 /false
关灯)。 -
String
:字符串类(注意:它是类名,不是关键字,但属于基础类型),一串文字(房子的门牌号 “橡树路123号”)。 -
byte
、short
、long
、float
:其他数值类型 -
null
:表示变量不引用任何对象 -
流程控制
if
、else
、switch
、case
、default
:条件判断for
、while
、do
:循环结构break
、continue
:跳出循环或终止当前迭代
-
String
:字符串类(注意:它是类名,不是关键字,但属于基础类型) -
byte
、short
、long
、float
:其他数值类型 -
null
:表示变量不引用任何对象
-
-
流程控制
if
、else
、switch
、case
、default
:条件判断for
、while
、do
:循环结构break
、continue
:跳出循环或终止当前迭代
面向对象关键字
-
类与对象
-
class
:定义类class
(类):房子的设计蓝图。 它定义了房子长什么样(有什么属性/变量)和能干什么(有什么功能/方法)。没有蓝图,你就不知道房子该怎么盖。public class MyCabin { ... }
就是你给这座小木屋起名叫MyCabin
的设计图。 -
new
:创建对象 -
extends
:类继承 -
implements
:实现接口(后续会学)
-
-
访问控制
private
、public
、protected
:成员访问权限static
:静态成员(类共享)final
:不可变(修饰类、方法、变量)
-
方法与构造器
void
:无返回值return
:返回方法结果this
:引用当前对象super
:引用父类对象
异常处理关键字
try
、catch
、finally
:异常捕获与处理throw
:手动抛出异常throws
:声明方法可能抛出的异常
其他重要关键字
package
、import
:包管理与导入类interface
:定义接口(后续会学)abstract
:抽象类或方法enum
:枚举类型
关键字书写的注意事项
一、关键字严格区分大小写
Java 的关键字全部为小写字母,且必须严格按小写书写。若使用大写或混合大小写,会导致编译错误或被视为普通标识符(如类名、变量名)。
错误示例
public CLASS HelloWorld { // 错误:CLASS不是关键字,应使用class
PUBLIC STATIC VOID main(String[] args) { // 错误:PUBLIC/STATIC/VOID不是关键字
INT age = 20; // 错误:INT不是关键字
}
}
正确示例
public class HelloWorld { // class是关键字,小写
public static void main(String[] args) { // public/static/void均为小写关键字
int age = 20; // int是小写关键字
}
}
二、避免与类名 / 接口名混淆
部分 Java 类名或接口名看起来像关键字,但实际上不是(如String
、Class
、System
)。这些名称允许作为标识符使用,但不建议这样做,以免降低代码可读性。
常见易混淆的非关键字
非关键字 | 说明 |
---|---|
String | 是类名,用于表示字符串(如String name = "Alice"; )。 |
Class | 是反射机制中的类,用于表示 Java 类的元数据(如Class<?> clazz = String.class; )。 |
System | 是系统类,提供标准输入 / 输出等功能(如System.out.println(); )。 |
Integer | 是包装类,用于封装基本类型int (如Integer num = 10; )。 |
三、特殊关键字的注意事项
null
关键字- 必须小写,表示引用变量不指向任何对象。
- 错误:
NULL
、Null
(会被视为未定义的变量或类名)。
true
和false
- 布尔值字面量,必须小写。
- 错误:
True
、False
(会被视为未定义的变量或类名)。
this
和super
- 用于引用当前对象或父类对象,必须小写。
- 错误:
This
、Super
(会被视为类名)。
四、示例对比
正确写法
public class Main {
public static void main(String[] args) {
boolean isStudent = true; // true是布尔字面量,小写
String name = null; // null是关键字,小写
if (isStudent) { // if是关键字,小写
System.out.println("Hello, student!"); // System是类名,首字母大写
}
}
}
错误写法
public Class Main { // 错误:Class应改为class
public Static Void main(String[] Args) { // 错误:Static/Void/Args均不符合规范
Boolean isStudent = True; // 错误:Boolean/True应改为boolean/true
String Name = NULL; // 错误:Name/NULL应改为name/null
If (isStudent) { // 错误:If应改为if
System.Out.Println("Hello"); // 错误:Out/Println应改为out/println
}
}
}
五、IDE 的辅助提示
现代 IDE(如 IntelliJ IDEA、Eclipse)会对关键字进行特殊高亮(通常为蓝色或紫色),而普通标识符(类名、变量名)会显示不同颜色。编写代码时,注意观察颜色区分,避免拼写错误。
在 Java 中,标识符(Identifier) 是用于给类、变量、方法、包等元素命名的符号。它与关键字不同,关键字是 Java 预定义的保留字,而标识符是开发者自定义的名称。以下是标识符的使用规则和注意事项:
标识符
一、标识符的命名规则
- 允许使用的字符
- 字母(
a-z
、A-Z
)、数字(0-9
)、下划线(_
)、美元符号($
)。 - 注意:不能使用空格、特殊符号(如
@
、#
、%
等)。
- 字母(
- 不能以数字开头
- 合法:
age
、_score
、$value
、user1
。 - 非法:
123name
(以数字开头)。
- 合法:
- 区分大小写
myVariable
和MyVariable
是不同的标识符。
- 不能与关键字冲突
- 非法:
class
、public
、if
(这些是关键字)。
- 非法:
- 无长度限制
- 可以使用任意长度的名称,但建议保持简洁且有意义。
二、标识符的命名规范(约定俗成)
- 类名
- 使用大驼峰命名法(PascalCase):每个单词首字母大写,如
HelloWorld
、StudentManager
。
- 使用大驼峰命名法(PascalCase):每个单词首字母大写,如
- 变量和方法名
- 使用小驼峰命名法(camelCase):第一个单词首字母小写,后续单词首字母大写,如
age
、getUserName
。
- 使用小驼峰命名法(camelCase):第一个单词首字母小写,后续单词首字母大写,如
- 常量名
- 全部大写,单词间用下划线分隔,如
MAX_VALUE
、PI
。
- 全部大写,单词间用下划线分隔,如
- 包名
- 全部小写,通常使用域名反转的形式,如
com.example.project
。
- 全部小写,通常使用域名反转的形式,如
三、示例对比
合法标识符
int age; // 变量名,小驼峰
String userName; // 变量名,小驼峰
public class Student { // 类名,大驼峰
public static final int MAX_SCORE = 100; // 常量,全大写
public void getInfo() { ... } // 方法名,小驼峰
}
package com.example; // 包名,全小写
非法标识符
int 123age; // 错误:以数字开头
String class; // 错误:与关键字冲突
public class 123User { // 错误:类名不能以数字开头
public static final int MAX-VALUE = 100; // 错误:包含非法字符'-'
}
四、特殊注意事项
$
符号的使用- 虽然允许使用
$
,但通常用于编译器生成的标识符(如内部类的命名),开发者应避免使用,以免混淆。
- 虽然允许使用
- 中文 / 其他语言字符
- Java 允许使用 Unicode 字符(如中文、日文)作为标识符,但不建议这样做,可能导致编码问题或降低代码可读性。
- 与关键字相似的名称
- 避免使用与关键字相似的名称,如
Class
(虽然合法,但易混淆,它是 Java 反射机制中的类名)。
- 避免使用与关键字相似的名称,如
变量
变量(Variable) 是存储数据的容器,它是程序中最基本的存储单元。变量有特定的数据类型,用于限制存储的数据种类,并在内存中占据一定的空间。以下是关于 Java 变量的详细介绍:
变量的基本概念
1. 变量的三要素
- 数据类型:指定变量可以存储的数据种类(如
int
、String
)。 - 变量名:合法的标识符,用于引用变量(如
age
、userName
)。 - 值:存储在变量中的数据(需与数据类型匹配)。
2. 声明与赋值
-
声明
:指定变量的类型和名称。
int age; // 声明一个整型变量age
-
赋值
:使用
=
为变量赋值。
age = 20; // 赋值 int score = 95; // 声明并赋值(初始化)
二、变量的数据类型
Java 是强类型语言,变量必须先声明类型,才能使用。数据类型分为两类:
1. 基本数据类型(Primitive Types)
类型 | 描述 | 范围 / 示例 |
---|---|---|
byte | 8 位有符号整数 | -128 到 127 |
short | 16 位有符号整数 | -32,768 到 32,767 |
int | 32 位有符号整数(默认) | -2,147,483,648 到 2,147,483,647 |
long | 64 位有符号整数 | 需加L 后缀,如100L |
float | 32 位单精度浮点数 | 需加F 后缀,如3.14F |
double | 64 位双精度浮点数(默认) | 如3.14 |
char | 16 位 Unicode 字符 | 单引号,如'A' 、'中' |
boolean | 布尔值 | 只有true 或false |
2. 引用数据类型(Reference Types)
-
类(Class):如String:Date
String name = "Alice"; // String是内置类
-
接口(Interface):后续学习。
-
数组(Array)
:存储同类型多个元素.
int[] numbers = {1, 2, 3}; // 整型数组
三、变量的作用域
变量的作用域指变量的有效范围,根据声明位置分为三种:
1. 局部变量(Local Variable)
-
声明位置:方法或代码块内部。
-
作用域:从声明处到所在方法或代码块结束。
-
注意
:使用前必须初始化。
public void example() { int x = 10; // 局部变量,仅在example()方法内有效 if (x > 5) { String message = "Hello"; // 仅在if块内有效 } // System.out.println(message); // 错误:超出作用域 }
2. 成员变量(实例变量)
-
声明位置:类内部、方法外部,无
static
修饰。 -
作用域:整个类,但需通过对象访问。
-
默认值:未赋值时有默认值int默认0,boolean默认false。
public class Student { String name; // 成员变量 int age; // 成员变量 public void display() { System.out.println(name + ", " + age); } }
3. 静态变量(类变量)
-
声明位置:类内部、方法外部,用
static
修饰。 -
作用域:整个类,可直接通过类名访问。
-
特点:所有对象共享同一个值。
public class Circle { static final double PI = 3.14; // 静态常量 double radius; public double getArea() { return PI * radius * radius; } }
四、变量的初始化
变量在使用前必须被初始化(赋值),否则会编译错误。
1. 基本类型初始化
int num = 0; // 声明并初始化
double price;
price = 9.99; // 先声明后初始化
boolean isDone = false; // 布尔值初始化
2. 引用类型初始化
String name = null; // 初始化为null(不指向任何对象)
name = "Alice"; // 赋值为字符串对象
int[] array = new int[5]; // 数组初始化,长度为5
五、变量的命名规范
- 遵循标识符规则:只能包含字母、数字、
_
、$
,不能以数字开头,不能是关键字。 - 使用小驼峰命名法:如
userName
、maxScore
。 - 见名知意:避免无意义的命名(如
a
、b
)。
六、示例代码
public class demo1 {
static int classCount = 0; // 静态变量(类变量)
String name; // 成员变量(实例变量)
private int age; // 私有成员变量
public void setAge(int age) { // 方法参数(局部变量)
if (age > 0) {
this.age = age; // this.age指向成员变量
}
}
public void displayInfo() {
String message = "姓名:" + name; // 局部变量
System.out.println(message + ",年龄:" + age);
}
public static void main(String[] args) {
VariableExample obj1 = new VariableExample();
obj1.name = "张三";
obj1.setAge(20);
classCount++; // 通过类名访问静态变量
VariableExample obj2 = new VariableExample();
obj2.name = "李四";
obj2.setAge(25);
classCount++;
System.out.println("总人数:" + classCount); // 输出2
obj1.displayInfo(); // 输出:姓名:张三,年龄:20
obj2.displayInfo(); // 输出:姓名:李四,年龄:25
}
}
七、常见问题
-
局部变量未初始化
int x; System.out.println(x); // 错误:局部变量未初始化
-
作用域混淆
if (true) { int num = 10; } System.out.println(num); // 错误:num超出作用域
变量所占的空间存储
在书写过程中我们总能看到什么类型的变量站多大的存储,那占了这存储能表述什么呢,怎么看变量的存储。
一、变量占用存储空间的本质
-
什么是存储空间?
计算机的内存(RAM)由大量存储单元组成,每个单元可存储特定类型的数据(如整数、字符、浮点数等)。- 每个存储单元有唯一的地址(类似房间编号),用于定位和访问数据。
- 不同数据类型占用的存储空间大小不同(由编程语言和系统决定),例如:
int
(整数)在 C 语言中通常占 4 字节(32 位),在 Python 中则根据数值动态调整。char
(字符)通常占 1 字节。
-
变量如何占用空间?
当声明一个变量时,程序会在内存中为其分配一块指定大小的存储空间,用于存放变量的值。例如:int age = 18; // 分配4字节空间存储整数18
二、关注变量存储空间的原因
1. 优化内存使用(避免资源浪费)
- 场景举例:
- 若只需存储 0~255 的整数,使用
int
(4 字节)会浪费 3 字节,改用unsigned char
(1 字节)更高效。 - 在嵌入式系统或内存受限的环境中(如单片机),合理分配空间可避免内存不足。
- 若只需存储 0~255 的整数,使用
- 影响:
- 内存资源有限,不合理使用可能导致程序崩溃或系统性能下降(如频繁的内存申请 / 释放会产生碎片)。
2. 数据类型匹配与精度丢失
-
类型不匹配的风险:
-
若将大类型数据存入小类型变量(如将long型存入int型),可能导致数据截断或溢出,引发逻辑错误。
int a = 300000; // 假设int占2字节,300000超过范围(最大值32767),会溢出为负数
-
在强类型语言(如 C、Java)中,编译器会检查类型匹配;在弱类型语言(如 Python)中,动态类型可能隐藏此类问题。
-
3. 程序性能与执行效率
- 访问速度差异:
- 不同数据类型在内存中的存储方式影响 CPU 读取速度。例如,CPU 对对齐数据(如 4 字节的
int
从 4 的倍数地址开始存储)的访问效率更高。
- 不同数据类型在内存中的存储方式影响 CPU 读取速度。例如,CPU 对对齐数据(如 4 字节的
- 缓存利用率:
- 合理使用小尺寸变量可让更多数据存入 CPU 缓存,减少对主存的访问,提升程序运行速度。
4. 跨平台兼容性
- 数据类型大小差异:
- 不同操作系统或编译器对数据类型的默认大小可能不同(如
int
在 32 位和 64 位系统中均为 4 字节,但long
在 32 位系统占 4 字节,64 位系统占 8 字节)。 - 若程序需在多平台运行,需显式指定类型大小(如使用
stdint.h
中的int32_t
、int64_t
),避免因平台差异导致错误。
- 不同操作系统或编译器对数据类型的默认大小可能不同(如
5. 调试与错误定位
- 内存泄漏与溢出:
- 动态分配内存(如 C 的
malloc
、C++ 的new
)后若未释放,会导致内存泄漏;数组越界访问可能覆盖其他变量的存储空间,引发难以调试的异常。 - 关注存储空间可帮助定位此类问题(如通过调试工具查看内存布局)。
- 动态分配内存(如 C 的
三、典型编程语言的变量存储特点
语言 | 特点 |
---|---|
C/C++ | 静态类型,需显式声明变量类型,存储空间固定,手动管理内存(易出错)。 |
Java | 静态类型,基本类型(如int 占 4 字节)存储空间固定,引用类型存地址。 |
Python | 动态类型,变量存储包含数据值和类型信息,空间占用动态调整(灵活性高但效率较低)。 |
JavaScript | 动态类型,弱类型,存储空间由引擎自动管理(如 V8 引擎的内存分配策略)。 |
java语言的变量类型转换
一、类型转换的分类
Java 的类型转换分为两种:自动类型转换(隐式转换) 和 强制类型转换(显式转换)。
二、自动类型转换(隐式转换)
1. 条件
- 小范围类型 → 大范围类型(如
int
转long
)。 - 数据类型兼容(如数值类型之间、子类对象转父类对象)。
2. 数值类型的自动转换规则
按范围从小到大排列:
byte → short → int → long → float → double
char → int
- 示例:
int num = 100; // int类型 long bigNum = num; // 自动转换为long(int→long) double d = 3.14f; // float→double(范围扩大)
3. 字符与整数的转换
-
char
可自动转为
int
(返回 Unicode 码值)。
char c = 'A'; // Unicode值为65 int code = c; // 自动转换为int,code=65
三、强制类型转换(显式转换)
1. 条件
- 大范围类型 → 小范围类型(如
double
转int
)。 - 需手动添加转换运算符:
(目标类型) 值
。
2. 语法
目标类型 变量名 = (目标类型) 源值;
-
示例:
double d = 3.14; int num = (int) d; // 强制转换,结果为3(小数部分被截断) long bigNum = 1000L; short s = (short) bigNum; // 若值超出short范围,会溢出
3. 注意事项
-
数据截断
:转换为整数时,小数部分直接丢弃。
double price = 9.99; int truncated = (int) price; // 结果为9
-
溢出风险
:若值超出目标类型范围,会导致溢出(结果可能为负数或错误值)。
int largeNum = 300; byte b = (byte) largeNum; // 300超出byte范围(-128~127),结果为44(溢出)
四、引用类型的转换
1. 向上转型(自动转换)
-
子类对象→父类类型(安全)。
class Animal { /* ... */ } class Dog extends Animal { /* ... */ } Dog dog = new Dog(); Animal animal = dog; // 自动转换(向上转型)
2. 向下转型(强制转换)
-
父类引用→子类类型
(需确保实际指向子类对象,否则运行时抛出ClassCastException)。
Animal animal = new Dog(); // 向上转型 Dog dog = (Dog) animal; // 向下转型(安全,animal实际是Dog) Animal animal2 = new Animal(); Dog dog2 = (Dog) animal2; // 运行时错误:ClassCastException
3. instanceof
运算符
-
作用
:检查对象是否为特定类型的实例,避免向下转型时的异常。
if (animal instanceof Dog) { Dog dog = (Dog) animal; // 安全转换 }
五、表达式中的类型自动提升
-
规则
:表达式中不同类型的数据混合运算时,会自动提升为范围最大的类型。
int a = 10; double b = 3.14; double result = a + b; // a自动提升为double(10.0),结果为13.14
六、常见错误与注意事项
-
不兼容类型转换
- 数值类型与布尔类型之间无法转换。
boolean isTrue = true; int num = (int) isTrue; // 编译错误:不兼容的类型
-
字符串与基本类型的转换
- 需使用包装类或
String
的方法,而非强制类型转换。
String str = "123"; int num = Integer.parseInt(str); // 正确:字符串→整数
- 需使用包装类或
-
浮点数与整数转换的精度丢失
float f = 1.23f; int i = (int) f; // 结果为1(丢失小数部分)
七、示例代码
public class TypeConversionExample {
public static void main(String[] args) {
// 自动类型转换
int intValue = 100;
long longValue = intValue; // int→long,自动转换
// 强制类型转换
double doubleValue = 3.99;
int truncated = (int) doubleValue; // 结果:3(截断小数)
// 溢出示例
int largeNumber = 300;
byte byteValue = (byte) largeNumber; // 结果:44(溢出)
System.out.println("溢出结果:" + byteValue); // 输出:44
// 引用类型转换
Animal animal = new Dog(); // 向上转型(自动)
if (animal instanceof Dog) {
Dog dog = (Dog) animal; // 向下转型(安全)
dog.bark(); // 调用Dog类的方法
}
// 表达式中的类型提升
int x = 5;
double y = 2.0;
double result = x / y; // x自动提升为double,结果:2.5
}
}
class Animal {
public void eat() {
System.out.println("动物进食");
}
}
class Dog extends Animal {
public void bark() {
System.out.println("汪汪叫");
}
}