变量、常量、作用域、关键字、修饰符、标识符、运算符20221222
变量、常量、作用域20241222
变量
◆ 变量是什么:就是可以变化的量!
◆Java是一种强类型语言,每个变量都必须声明其类型
◆Java变量是程序中最基本的存储单元,其要素包括变量名,变量类型和作用域。
◆ 使用逗号隔开在一行定义多个同类型变量,可以但是不推荐
//int data_04=1,data_05=2,data_06=3;//可以但是不推荐 int data_04=1; int data_05=2; int data_06=3;注意事项:
◆ 每个变量都有类型,类型可以是基本类型,也可以是引用类型
◆ 变量名必须是合法的标识符
◆变量声明是一条完整的语句,因此每一个声明都必须以分号结束
变量作用域
◆类变量
1. 类变量(静态变量,
static)
定义位置: 类内部,使用
static关键字修饰。作用域: 作用域是整个类,可以通过类名直接访问,或者通过实例对象访问。
生命周期: 类变量的生命周期从类加载开始,一直到程序结束。
特点: 类变量属于类本身而不是某个实例,所有实例共享一个类变量。
class Demo { static int classVar = 10; // 类变量 public static void main(String[] args) { System.out.println(Demo.classVar); // 通过类名访问类变量 } }输出:
10
◆实例变量
2. 实例变量(成员变量)
定义位置: 类内部,但不使用
static修饰。作用域: 作用域是整个类,但它必须通过实例化对象来访问。
生命周期:实例变量的生命周期与对象的生命周期一致。当创建对象时,实例变量被分配内存,并且对象被销毁时,实例变量随对象一起销毁。
特点: 每个对象拥有自己独立的实例变量。
class Demo { int instanceVar = 20; // 实例变量 public static void main(String[] args) { Demo demo1 = new Demo(); Demo demo2 = new Demo(); demo1.instanceVar = 30; // 修改 demo1 对象的实例变量 demo2.instanceVar = 40; // 修改 demo2 对象的实例变量 System.out.println(demo1.instanceVar); // 输出 30 System.out.println(demo2.instanceVar); // 输出 40 } }输出:
30
40
◆局部变量
3. 局部变量
定义位置: 方法内部或代码块(如
if、for、while等语句块)内定义的变量。作用域: 仅在定义它的方法或代码块内有效。其他方法或代码块不能访问该局部变量。
生命周期: 局部变量的生命周期仅限于方法执行期间。一旦方法执行完成,局部变量就会被销毁。
特点: 必须在使用前初始化。
/** * @Desciption:变量作用域 * @Author:胖乎乎 * @Time:2024/12/22 * */ public class demo04_Variables_Scope { //class 类空间 可以定义方法,也可以定义一些属性:变量 //main 方法 主程序方法 public static void main(String[] args) { //定义局部变量,定在在方法、代码块static{}中的变量 //生命周期只在两个大括号内,必须声明和初始化值 int i=10; System.out.println("i"); } //其他方法 public void add(){ } }总结:
1.变量不都要在使用前初始化吗?为什么要强调局部变量在使用前要初始化
是的,你说得对,所有变量在使用前都必须初始化,这一点适用于类变量、实例变量和局部变量。不过,强调局部变量必须在使用前初始化,是因为局部变量有一些特定的行为和规则,这些规则在其他类型的变量中并不完全相同。
(1). 局部变量的初始化要求
在 Java 中,局部变量必须在声明后赋值并初始化才能使用。如果你试图使用一个未初始化的局部变量,编译器会报错。这是 Java 语言的设计决定的,旨在避免因未初始化变量导致的潜在错误。
示例:未初始化的局部变量会报错
public class Demo { public void method() { int x; // 局部变量 x 声明但未初始化 System.out.println(x); // 错误:变量 x 可能尚未初始化 } public static void main(String[] args) { Demo demo = new Demo(); demo.method();//此处调用出错 } }(2). 类变量和实例变量的初始化规则
与此不同,类变量和实例变量的初始化规则有所不同:
类变量(静态变量):如果你没有显式地给类变量赋初值,它会自动被赋予默认值。例如,
int类型的类变量会被初始化为0。实例变量:实例变量如果没有显式赋值,Java 会在对象创建时为其分配默认值。例如,
int类型的实例变量会初始化为0,boolean类型会初始化为false,引用类型(如String)会初始化为null。示例:类变量和实例变量的默认值
public class Demo { static int classVar; // 类变量,默认为 0 int instanceVar; // 实例变量,默认为 0 public static void main(String[] args) { Demo demo = new Demo(); System.out.println(classVar); // 输出 0 System.out.println(demo.instanceVar); // 输出 0 } }输出:
0
0变量初始化总结:
类变量 和 实例变量可以在声明时不初始化,它们会自动被赋予默认值。
局部变量 必须在声明后被显式必须初始化,否则编译器会抛出错误。
2.类变量可以修改吗?怎么修改
是的,类变量的值是可以修改的。类变量(也叫静态变量)在 Java 中属于类本身,而不是某个具体的实例。你可以通过类名或类的实例来修改类变量的值。
修改类变量的方式:
通过类名修改类变量的值:
- 这是推荐的做法,因为类变量属于类本身,不需要创建对象就可以访问和修改它。
通过类的实例修改类变量的值:
- 虽然可以通过实例来访问类变量,但这种方式并不推荐,因为它可能引起混淆,类变量本身是属于类的,最好通过类名来访问。
class Demo { // 类变量,使用 static 修饰 static int classVar = 100; public static void main(String[] args) { // 通过类名修改类变量的值 Demo.classVar = 200; // 通过类的实例修改类变量的值 Demo demo = new Demo(); demo.classVar = 300; // 打印类变量的值 System.out.println("类变量通过类名修改后的值: " + Demo.classVar); // 输出:300 System.out.println("类变量通过实例修改后的值: " + demo.classVar); // 输出:300 } }通过类名修改类变量:
Demo.classVar = 200;
通过类名直接修改类变量值,这种方式是推荐的,因为它清楚地表明了该变量属于类。通过实例修改类变量:
demo.classVar = 300;
虽然你也可以通过实例demo来修改类变量的值,但不推荐这么做。通过实例修改类变量容易让人混淆,认为它是实例变量,而实际它是类变量。3.实例变量可以修改吗?怎么修改
是的,实例变量是可以修改的。实例变量属于对象(实例),每个对象都有自己独立的实例变量值。你可以通过实例化的对象来修改实例变量的值。
修改实例变量的方式:
- 通过实例对象修改实例变量的值:
- 实例变量的值通常是在对象被创建时分配的,但你可以通过对象访问并修改它。
- 通过方法修改实例变量的值:
- 实例变量可以通过对象的方法(尤其是 setter 方法)来修改,常见于封装(Encapsulation)设计模式。
class Demo { // 实例变量,属于对象 int instanceVar = 10; // 方法,用于修改实例变量的值 public void setInstanceVar(int value) { instanceVar = value; } public static void main(String[] args) { // 创建 Demo 对象 Demo demo = new Demo(); // 通过对象修改实例变量的值 demo.instanceVar = 20; // 打印实例变量的值 System.out.println("修改后的实例变量值: " + demo.instanceVar); // 输出:20 // 使用方法修改实例变量的值 demo.setInstanceVar(30); // 打印修改后的实例变量的值 System.out.println("通过方法修改后的实例变量值: " + demo.instanceVar); // 输出:30 } }Demo.instanceVar 输出是什么还是10吗?
在你提供的代码中,
Demo.instanceVar是不合法的,因为instanceVar是一个 实例变量,而不是 类变量。实例变量需要通过 对象 来访问,不能直接通过类名访问。正确的访问方式:你可以通过 对象 来访问和修改
instanceVar,如demo.instanceVar,但 不能通过类名Demo.instanceVar来访问实例变量,因为它属于对象,而不是类。我在新建一个对象demo1,他的instanceVar 的值是多少
在你提供的代码中,当你创建一个新的
Demo对象(如demo1)时,demo1的instanceVar值将会是 10,这是因为instanceVar是实例变量,每个对象都有自己独立的实例变量。4.变量作用域总结
变量类型 定义位置 作用域 生命周期 初始化要求 类变量 类内, static修饰全类,类中所有方法和对象都可以访问 类加载开始,到程序结束 不需要(默认值) 实例变量 类内, static不修饰全类,但只能通过对象访问 与对象同生命周期,创建对象时分配内存 不需要(默认值) 局部变量 方法内部,或代码块内 仅限于定义它的方法或代码块 方法执行期间或代码块执行期间 必须初始化 5.变量的优先级
如果类变量、实例变量和局部变量的名字相同,Java 会根据作用域优先级来决定访问哪个变量:
局部变量:优先级最高,局部变量会遮蔽实例变量和类变量。
实例变量:如果没有局部变量,它将被使用。
类变量:最后才会使用类变量。
class demo04_Variables_Scope { // 类变量,属于类 static int var = 100; // 实例变量,属于对象 int var = 200; // 方法,演示变量的作用域 public void testMethod() { // 局部变量,属于方法 int var = 300; // 打印当前方法内的局部变量值 System.out.println("局部变量 var: " + var); // 输出:300 // 在方法内部访问实例变量 System.out.println("实例变量 var: " + this.var); // 输出:200 // 访问类变量(静态变量) System.out.println("类变量 var: " + demo04_Variables_Scope.var); // 输出:100 } public static void main(String[] args) { // 创建对象 demo04_Variables_Scope demo = new demo04_Variables_Scope(); demo.testMethod(); } }
代码理解:
1.类变量
class Test { // 类变量,使用 static 修饰 static int classVar = 100; public static void main(String[] args) { // 通过类名修改类变量的值 Test.classVar = 200; // 通过类的实例修改类变量的值 Test test = new Test(); Test.classVar = 300; // 打印类变量的值 System.out.println("类变量通过类名修改后的值: " + Test.classVar); // 输出:300 System.out.println("类变量通过实例修改后的值: " + test.classVar); // 输出:300 // 创建另一个 Test 对象 Test test1 = new Test(); System.out.println("类变量通过实例修改后的值: " + test1.classVar); // 输出:300 } }解释:
通过类名修改类变量的值:
Test.classVar = 200;这里通过
Test.classVar修改了类变量的值,将其设置为200。但是后面又将类变量的值修改为300,所以最终的值是300。通过实例修改类变量的值:
Test test = new Test(); Test.classVar = 300;通过实例
test修改类变量的值,仍然会影响所有实例的类变量,因为类变量是所有实例共享的。即使你是通过实例来修改类变量的值,其他实例仍然会看到相同的值。打印输出:
- 通过类名修改后的值:
Test.classVar被修改为300,因此第一次输出是300。- 通过实例修改后的值:
test.classVar也是300,所以第二次输出是300。- 另一个实例
test1的类变量值: 即使是通过test1创建了新的对象,test1.classVar也是300,因为classVar是类变量,所有实例共享同一份数据。2.实例变量
**实例变量,属于对象**
class Test { // 实例变量,属于对象 int instanceVar = 10; // 方法,用于修改实例变量的值 public void setInstanceVar(int value) { instanceVar = value; } public static void main(String[] args) { // 创建 Test 对象 Test test = new Test(); // 通过对象修改实例变量的值 test.instanceVar = 20; // 打印实例变量的值 System.out.println("修改后的实例变量值: " + test.instanceVar); // 输出:20 // 使用方法修改实例变量的值 test.setInstanceVar(40); // 打印修改后的实例变量的值 System.out.println("通过方法修改后的实例变量值: " + test.instanceVar); // 输出:40 // 创建另一个 Test 对象 test2 Test test2 = new Test(); // 打印 test2 的实例变量值 System.out.println(test2.instanceVar); // 输出:10 } }常量
初始化(initialize)后不能再改变值!不会变动的值。所谓常量可以理解成一种特殊的变量,它的值被设定后,在程序运行过程中不允许被改变
final 常量类型 常量名=值;
final double PI=3.14;
常量名一般使用大写字符
public class Demo06_Constant { //修饰符不区分先后位置 final static double PI=3.14159265358979323846 static final double PI = 3.14159265358979323846; public static void main(String[] args) { System.out.println(PI); } }命名规范
所有变量、方法、类名:见名知意
类变量:首字母小写和驼峰原则:monthSalary 除了第一个单词以外,后面的单词首字母大写lastname lastName
局部变量:首字母小写和驼峰原则
常量:大写字母和下划线:MAX_VALUE
类名:首字母大写和驼峰原则: Man,GoodMan
方法名:首字母小写和驼峰原则:run(),runRun()
关键字、修饰符、标识符20221222
1. 关键字 (Keyword)
关键字是 Java 语言中具有特殊意义的保留字,不能用作变量名、方法名、类名等标识符。它们是 Java 语言的基本组成部分,每个关键字都在编译时具有特定的作用。
常见的关键字:
- 控制结构:
if,else,while,for,switch,break,continue,return等- 数据类型:
int,boolean,char,double,float,long,byte等- 访问控制:
public,private,protected,default- 修饰符:
static,final,abstract,synchronized,volatile等- 类和对象相关:
class,interface,extends,implements,new,this,super,instanceof- 异常处理:
try,catch,throw,throws,finally- 其他:
package,import,void,native,enum,assert,instanceof等2. 修饰符 (Modifier)
修饰符是用于修饰类、方法、变量等的关键字,用来控制它们的访问权限、行为、特性等。修饰符可以分为两大类:访问修饰符和非访问修饰符。
访问修饰符:
public:表示类、方法或变量对所有其他类可见。private:表示类的成员只对当前类可见。protected:表示类的成员对当前类、同一包中的类以及子类可见。default(包访问权限):没有修饰符时,表示类成员仅对同一包内的类可见。非访问修饰符:
static:表示类的成员是类级别的,属于类本身,而不是对象实例。final:表示变量是常量,不能修改;方法不能被重写;类不能被继承。abstract:表示类是抽象类,不能实例化;方法是抽象方法,必须由子类实现。synchronized:表示方法是线程安全的,确保只有一个线程可以执行该方法。volatile:表示变量的值可能会在不同线程中发生变化,告诉编译器不要对该变量进行优化。transient:表示变量不参与序列化过程。native:表示方法是使用其他语言(通常是 C 或 C++)实现的本地方法。3. 标识符 (Identifier)
标识符是程序员用来命名类、方法、变量、包、常量等的名称。标识符可以是字母、数字、下划线 (
_) 或美元符号 ($),但不能以数字开头。标识符的规则:
- 标识符只能包含字母、数字、下划线和美元符号。
- 标识符不能以数字开头。
- 标识符不能是 Java 的关键字。
- 标识符区分大小写(
variable和Variable是不同的标识符)。
运算符20241222
1.()的优先级最高,因此可以多打一些()提高代码的可读性!!
尽管 Java 中有运算符优先级规则,但不同人对优先级的理解程度不同,某些复杂的运算表达式使用括号会显得更加清晰。例如,对于一个长的算数表达式,括号可以帮助显式地表达计算顺序,避免产生歧义。
int result = 10 + 5 * 3;int result = 10 + (5 * 3);if (a > 10 || b < 5 && c == 20) { // some code }if (a > 10 || (b < 5 && c == 20)) { // some code }2.分类总览
小tips:Ctrl+D:复制当前行到下面一行
/** * @classification1:算术运算符 +、-、*、/、%(模:取余)、++(自增)、--(自减) * @classification2:赋值运算符 = * @classification3:关系运算符 >、<、>=、<=、==、!=(不等于)、instanceof * @classification4:逻辑运算符 &&(与)、||(或)、!(非) * @classification5:位运算符(注意笔试/面试) &(与)、|(或)、^(异或)、~(取反)、>>(右移(重要))、<<(左移(重要))、>>>(了解即可) * @classification6:条件运算符 A?B:C 表达式1 ?表达式 2 :表达式 3 * @classification7:扩展赋值运算符 +=、-=、*=、/= * @classification8:字符串连接符 + */2.1算术运算符 +、-、*、/、%(模:取余)、++(自增)、--(自减)
public class Demo1 { public static void main(String[] args) { int a = 10; int b = 20; System.out.println(a + b);//30 System.out.println(a - b);//-10 System.out.println(a * b);//200 System.out.println(a / b);//10除20=0.5,但a,b均为int型,因此结果为0 System.out.println(a / (double)b);//将其中一个强制转为double型即可得出正确答案 System.out.println(b % a);//b对a取余数 0 } }++自增、- - 自减
++a :先自增再做其他运算
a++:先做其他运算再自增
public class Demo1 { public static void main(String[] args) { int a = 1; int b = a++;//b=a=1,a=a+1=2(先赋值后自增) int c = ++a;//a=a+1=2+1=3,c=a=3(先自增后赋值) System.out.println(a);//输出3 System.out.println(b);//输出1 System.out.println(c);//输出3 } }public class Demo03 { public static void main(String[] args) { int a = 1; int b = 1; System.out.println(a);//1 System.out.println(b);//1 System.out.println(a++>=2);//同样是先比较再自增 //false a=2 System.out.println(++b>=2);//先自增再比较 //true b=2 System.out.println(a);//2 System.out.println(b);//2 } }2.2赋值运算符 =
//=并不表示等于,等于是== a = b;//将b的值赋值给a a == b;//表示a等于b2.3关系运算符 >、<、>=、<=、==、!=(不等于)、instanceof
注意:关系运算符返回的结果是一个布尔值,ture或false
public class Demo1 { public static void main(String[] args) { int a = 10; int b = 20; System.out.println(a>b);//返回false System.out.println(a<b);//返回true System.out.println(a==b);//返回false System.out.println(a!=b);//返回true } }2.4逻辑运算符 &&(与)、||(或)、!(非)
public class Demo1 { public static void main(String[] args) { boolean a = true; boolean b = false; System.out.println("a && b:"+(a&&b));//逻辑&&(与):两个变量为真则为真 false System.out.println("a || b:"+(a||b));//逻辑||(或):一个变量为真则为真 true System.out.println("!b:"+(!b));//逻辑非(!):若为真结果则为假,若为假结果则为真 true } }注意:短路运算:在&&运算中,若前面的表达式为false,则后面的表达式不会执行
public class Demo1 { public static void main(String[] args) { int a = 1; boolean b = (a>3)&&(a++>3);//a>3为假,短路运算原则:后面的表达式不执行 System.out.println(b);//输出false System.out.println(a);//输出1,a还是为1 } }2.5位运算符(注意笔试/面试) &(与)、|(或)、^(异或)、~(取反)、>>(右移(重要))、<<(左移(重要))、>>>(了解即可)
&、|、^、~
A = 1100 0110 B = 0011 1100 -------------------------------------------- A&B = 0000 0100 (与&:两个1则为1,其余为0) A|B = 1111 1110 (或|:两个0则为0,其余为1) A^B = 1111 1010 (异或^:两个相同则为0,不同则为1) ~A = 0011 1001 (取反~:若是1则为0,若是0则为1)<<、>>:效率极高!!
public class Demo1 { public static void main(String[] args) { int a = 2; int b =(a<<3);//2<<3 = 2*2*2*2(2左移3位) System.out.println(b);//输出16 /* 2*8=16 //2*2*2*2=16(2的4次方) << : *2 >> : /2 ---------------------------- //二进制移位,1向左移动一位等于*2 0000 0001:1 0000 0010:2 0000 0100:4 0000 1000:8 0001 0000:16 (2左移3位) */ } }2.6条件运算符 A?B:C 表达式1 ?表达式 2 :表达式 3
表达式1 ?表达式 2 :表达式 3
如果表达式1正确则输出表达式2,否则输出表达式3
int c = 10; int d = 20; //如果c等于d则e=c,若不等于则e=c+d int e =(c==d) ? c :c + d; System.out.println(e);//输出结果为302.7扩展条件运算符 +=、-=、*=、/=
例如:a+=b意为a=a+b
int c = 10; int d = 20; c += d;//c=c+d System.out.println(c);//输出302.8字符串连接符(面试考题) +
public class Demo1 { public static void main(String[] args) { //字符串连接符'+':若一方为String类型,则会将另一方转为String类再进行拼接 int a = 10; int b = 20; System.out.println(""+a+b);//输出1020 System.out.println(a+b+"");//输出30,因为String类型在后面,所以前面的a+b会先运算再进行拼接 } }System.out.println(""+a+b);//输出1020
System.out.println(a+b+"");//输出30,因为String类型在后面,所以前面的a+b会先运算再进行拼接
数据优先级
public class Demo02 { public static void main(String[] args) { double data_01=231312.324123; float data_02=3.12434532f; long data_03=123456789L; int data_04=123; short data_05=1234; char data_06='a'; byte data_07=127; boolean data_08=true; /* System.out.println((String) (data_01+data_02+data_03+data_04+data_05+data_06+data_07)); System.out.println((String) (data_02+data_03+data_04+data_05+data_06+data_07)); System.out.println((String) (data_03+data_04+data_05+data_06+data_07)); System.out.println((String) (data_04+data_05+data_06+data_07)); System.out.println((String) (data_05+data_06+data_07)); System.out.println((String) (data_06+data_07)); System.out.println((String) data_07); */ System.out.println((data_01+data_02+data_03+data_04+data_05+data_06+data_07)); System.out.println((data_02+data_03+data_04+data_05+data_06+data_07)); System.out.println((data_03+data_04+data_05+data_06+data_07)); System.out.println((data_04+data_05+data_06+data_07)); System.out.println((data_05+data_06+data_07)); System.out.println((data_06+data_07)); System.out.println(data_07); } }输出结果
1.236896854484683E8
1.23458368E8
123458370
1581
1458
224
127在 Java 中,字符(
char)和字节(byte)在进行算术运算时,会被自动转换为数值型(int),因此data_06 + data_07的结果是一个int。数据类型大小及转换规则
double(64 位、8字节)> float(32 位、4字节)> long(64 位、8字节)> int(32 位、4字节)> char(16位、2字节)>short(16 位、2字节)> byte(8 位、1字节)


浙公网安备 33010602011771号