变量
1. 概念:变量是用来存储数据的命名容器并在程序的不同部分使用它。
2. 语法:数据类型 变量名称 = 初始值;
可以这样理解: **数据类型:**鱼缸 **变量名称:**鱼的名字 **变量的值:**鱼缸里装的鱼或数量数量
数据类型
基本数据类型
- 整型:
1. byte
:8位,有符号整数(-128到127)
2. short
:16位,有符号整数(-32768到32767)
3. int
:32 位,有符号整数(-2^31 到 2^31-1)
4. long
:64 位,有符号整数(-2^63 到 2^63-1)
- 浮点型:
1. float
:32 位,单精度浮点数
2. double
:64 位,双精度浮点数
- 字符型:
1. char
:16 位,表示单个 Unicode 字符('\u0000' 到 '\uffff')
- 布尔型:
1. boolean
:只能取两个值之一:true 或 false
tip:位数越多,数据的表示范围和精度越大,但同时也需要更多的内存。
引用数据类型
类(Class):如 String, Scanner, 自定义的类等。
1. String
- 用于存储文本,例如"Hello World"。字符串值用双引号括起来
2. char
- 存储单个字符,如"a"或"B"。字符值用单引号括起来
接口(Interface):如 Runnable, Serializable 等。
数组(Array):如 int[], String[] 等。
变量声明
声明一个变量时需要指定变量的类型,可以理解为空的鱼缸,没有水和鱼在刚里面,例如:
int age;
给鱼缸加水放鱼,就表示给变量赋值,上面定义了一个int类型的鱼,int类型的鱼属于整型,只能放阿拉伯数字,例如:
int age = 1
每个鱼缸只能放同一种类的鱼,鱼缸(数据类型)限定鱼(变量名)的种类表示不同的数据类型,如整型、字符型等。
而鱼缸装不下的鱼可以理解为变量类型不匹配,比如将字符型鱼放入布尔型鱼缸里。
数据类型转换
如果说,你偏要这么叛逆,非要把字符型鱼放入布尔型鱼缸里也不是不行,有两种方法:
- 隐式类型转换 (自动) - 从小类型到大类型,不需要强制转换符
byte
->short
->char
->int
->long
->float
->double
- 强制类型转换 (手动) - 从大类型到小类型,需要强制转换符实现强制转换
double
->float
->long
->int
->char
->short
->byte
发生在较小的数据类型自动转换为较大的数据类型时。Java 会自动进行这种转换,因为目标类型可以包含源类型的所有值。发生在将较大的数据类型转换为较小的数据类型时。由于目标类型的范围可能不能包含源类型的所有值,因此需要强制转换符。
当初学这一部分的时候我是比较困惑的,为什么大类型可以包含小类型,为什么不是从大类型到小类型可以自动,偏偏是由小到大的去包容?
现在我理解了,其实根本不是包容不包容的问题。
拿byte和short举例子。
1. 可能的数据丢失:
short
:16位,-32768到32767
byte
:8位,-128到127
short
的范围比 byte
大。如果 short
的值超出了 byte
的范围,那么在转换为 byte 时可能会丢失数据或产生不正确的结果。
举一个显示里的例子,你头从门缝里挤进去了,但不一定回得来,虽然很扯淡,但这类新闻还是有的。
数据溢出:。
如果 short 的值超出了 byte 的范围,转换时会发生溢出。比如,如果 short 的值是 130,它超出了 byte 的范围,直接转换会导致结果不符合预期(例如,130 转换为 byte 时,结果是 -126)。
这个拿钱举例,你的大号存钱罐里的人民币可能转到小号存钱罐,但也可能有几个硬币塞不下。
变量作用域
变量在程序中可见和可访问的范围。不同作用域的变量可能会影响程序的行为和变量的生命周期。
对于这句话我的理解是:你把鱼缸放家里和家外面的区别,放家里只能你看,但放家外面,甚至直接倒在鱼塘里,你的鱼可以被许多人看,还有可能被别人钓走。
1. 全局变量
老实说,我看见过两个版本的说法,一个是:
在 Java 中,通常没有真正的全局变量,因为所有的变量都必须在类内部定义。>
另一个是:
成员变量又可以分为 全局变量(又叫实例变量) 和 静态变量(也叫类变量)
但我更倾向于没有,类似的概念可以通过类变量来实现。
(免责声明:如果有人看我这个,还是大佬的话,持有不同意见,别喷,我也是菜鸡,我也还在学习中)
2. 类变量
类变量是定义在类中的变量,并使用 static
修饰符修饰。它属于类本身,而不是类的任何一个实例。
特点:
定义位置:在类的内部,使用 static 修饰符修饰。
生命周期:类变量在类加载时创建,程序运行期间一直存在。
访问范围:可以通过类名直接访问,也可以通过对象访问,但通常建议通过类名访问。
public class MathUtils {
static int count = 0; // 类变量
public static void incrementCount() {
count++;
}
public static void displayCount() {
System.out.println("Count: " + count);
}
}
public class Main {
public static void main(String[] args) {
MathUtils.incrementCount();
MathUtils.displayCount(); // 输出: Count: 1
}
}
理解为在自己房间里放的鱼(变量)只能在这个房间(代码块)中看到。不能在家里的其他房间(代码块)中看到这个房间里的鱼。
实例变量
实例变量是定义在类中的变量,但不在任何方法内部。它属于类的一个实例(对象),每个对象都有自己的实例变量。
特点:
定义位置:在类的内部,但不在方法、构造函数或代码块内。
生命周期:实例变量的生命周期与对象的生命周期一致。
访问范围:可以在类的所有方法中访问,必须通过对象来访问。
public class Car {
String color; // 实例变量
public void displayColor() {
System.out.println("Color: " + color); // 可以访问实例变量 color
}
}
public class Main {
public static void main(String[] args) {
Car myCar = new Car();
myCar.color = "Red"; // 访问实例变量
myCar.displayColor(); // 输出: Color: Red
}
}
理解为每个房间(对象)都有一个自己的鱼缸(实例变量)。虽然每个房间的鱼缸都可以放不同的鱼,但只要你在家里,你都可以看到这些鱼缸里的鱼(实例变量)。这些鱼缸在整个家中(类的所有方法和代码块)都可见。
局部变量
局部变量是定义在方法、函数或代码块内部的变量。它只能在其所在的代码块内访问,代码块外部无法访问。
特点:
定义位置:在方法内部、循环体内或条件语句内。
生命周期:局部变量在方法执行时创建,方法执行完毕后销毁。
访问范围:只能在其所在的方法或代码块内部访问。
public class Main {
public static void main(String[] args) {
int x = 10; // 局部变量 x
if (x > 5) {
int y = 20; // 局部变量 y
System.out.println("y = " + y); // 可以访问 y
}
System.out.println("y = " + y); // 编译错误,y 不能在 if 块外部访问
}
}
理解为公共鱼缸(类变量)在整个大楼(类的所有实例)中都是一样的,每个人(每个实例)都能看到这个公共鱼缸里的鱼。这个鱼缸不属于任何特定的房间(对象),而是整个大楼的一部分(类的所有实例)。
作用域与包容性
- 局部变量的作用域最小,仅在定义的位置可见。
- 实例变量的作用域包含了局部变量的作用域范围,加上类的所有方法和代码块。
- 类变量的作用域最大,包含了实例变量的作用域范围,并且在整个类内可见。