当前位置: 首页 > news >正文

java基础概念(二)----变量(附练习题)

在 Java 语言中,变量是程序中存储数据的基本单元,它是内存中的一块存储空间,用于存放可以变化的值。以下是关于 Java 变量的详细知识:

一、变量的内存分配细节

  1. 基本数据类型变量

    • 直接存储数据值,分配在栈内存中(局部变量)或堆内存中(成员变量,作为对象的一部分)。
    • 例如:int a = 10; 中,a 直接存储 10 这个值。
  2. 引用数据类型变量

    • 变量本身存储的是对象在堆内存中的地址(引用),变量名和引用存放在栈内存(局部变量)或堆内存(成员变量)。
    • 例如:String s = new String("test"); 中,s 存储的是堆中字符串对象的地址,而非 "test" 本身。
    • 多个引用可以指向同一个对象,修改对象内容会影响所有引用该对象的变量。

二、变量的默认值深入解析

只有成员变量(实例变量)和类变量(静态变量) 有默认值,局部变量必须显式初始化:

数据类型默认值
byte, short, int, long0
float, double0.0
char'\u0000'(空字符)
booleanfalse
引用类型null

示例:

class DefaultValues {// 成员变量 - 有默认值int num;          // 默认0boolean flag;     // 默认falseString text;      // 默认null// 静态变量 - 有默认值static double pi; // 默认0.0public void method() {// 局部变量 - 无默认值,必须初始化int localVar;// System.out.println(localVar); // 编译错误:可能尚未初始化变量}
}

三、变量的作用域与生命周期

  1. 局部变量

    • 声明在方法、构造器、循环、条件语句等代码块中。
    • 作用域:从声明处到包含它的最近一对{}结束。
    • 生命周期:进入作用域时创建,离开作用域时销毁。
  2. 实例变量

    • 声明在类中,方法之外,无static修饰。
    • 作用域:整个类(所有非静态方法均可访问)。
    • 生命周期:随对象创建而存在,随对象被垃圾回收而销毁。
  3. 静态变量

    • 声明在类中,方法之外,有static修饰。
    • 作用域:整个类(静态方法和非静态方法均可访问)。
    • 生命周期:随类的加载而初始化,随类的卸载而销毁(通常是程序结束时)。

示例:

public class VariableLifecycle {// 静态变量 - 类加载时初始化static int staticVar = 10;// 实例变量 - 对象创建时初始化int instanceVar = 20;public void method() {// 局部变量 - 方法调用时创建int localVar = 30;if (true) {// 局部变量 - 仅在该代码块内有效int blockVar = 40;System.out.println(blockVar); // 有效}// System.out.println(blockVar); // 无效,已超出作用域}
}

四、变量的命名细节与惯例

  1. 硬性规则

    • 必须以字母、_$开头,后续可跟字母、数字、_$
    • 长度无限制,但不宜过长。
    • 区分大小写(ageAge是两个不同变量)。
    • 不能使用 Java 关键字(如intclassfor等)和保留字(如gotoconst)。
  2. 软性惯例

    • 变量名采用小驼峰式命名(lowerCamelCase):第一个单词首字母小写,后续单词首字母大写,如studentNamemaxValue
    • 避免使用单字母命名(除了循环变量如ijk)。
    • 避免使用拼音或拼音与英文混合,推荐使用英文单词。
    • 布尔类型变量通常以ishascan等前缀开头,如isValidhasPermission

五、类型转换的深入理解

  1. 自动类型转换(拓宽转换)

    • 规则:从低精度 / 小范围类型向高精度 / 大范围类型转换,无需显式声明。
    • 转换顺序(基本类型):
      byte → short → int → long → float → double
      char → int → long → float → double
    • 注意:char类型可以自动转换为int(因为字符在 Java 中对应 Unicode 编码值),但byte/short不能自动转换为char(可能为负数)。

    示例:

    char c = 'A'; // 'A'的Unicode值是65
    int num = c;  // 自动转换,num的值为65byte b = 10;
    short s = b;  // 自动转换
    // char ch = b; // 编译错误,byte不能自动转char
    
  2. 强制类型转换(缩窄转换)

    • 规则:从高精度 / 大范围类型向低精度 / 小范围类型转换,必须显式声明,可能导致精度丢失或溢出。
    • 语法:目标类型 变量 = (目标类型)源值;

    示例 1(精度丢失):

    double d = 3.14159;
    int i = (int)d; // 结果为3,小数部分被截断
    

    示例 2(数值溢出):

    int bigNum = 2147483647; // int的最大值
    int overflow = (int)(bigNum + 1); // 结果为-2147483648(溢出)
    

    示例 3(引用类型的强制转换):

    Object obj = "Hello";
    String str = (String)obj; // 正确,obj实际指向String对象Object numObj = 100;
    // String str2 = (String)numObj; // 运行时错误:ClassCastException
    

六、变量的特殊情况

  1. final 变量

    • final修饰的变量一旦赋值就不能再修改(常量)。
    • 声明时可以不初始化,但必须在使用前初始化(称为 "空白 final 变量")。
    • 局部变量、实例变量、静态变量均可被final修饰。

    示例:

    final int MAX_SIZE = 100; // 声明时初始化
    // MAX_SIZE = 200; // 编译错误:不能修改final变量class FinalExample {final int blankFinal; // 空白final变量// 必须在构造器中初始化空白final变量public FinalExample(int value) {blankFinal = value;}
    }
    
  2. 参数变量

    • 方法或构造器的参数本质上是局部变量,其值由调用者传入。
    • 作用域:整个方法或构造器体内。

    示例:

    public void printMessage(String message) { // message是参数变量System.out.println(message);
    }
    
  3. 数组元素作为变量

    • 数组中的每个元素都是一个变量,类型与数组类型一致。
    • 数组元素的访问通过索引实现,索引从 0 开始。

    示例:

    int[] numbers = new int[3];
    numbers[0] = 10; // 数组元素变量赋值
    numbers[1] = 20;
    

七、变量使用的最佳实践

  1. 最小作用域原则:变量应在尽可能小的作用域内声明,减少命名冲突和内存占用。

    // 推荐
    if (condition) {int temp = calculate();System.out.println(temp);
    }// 不推荐(扩大了作用域)
    int temp;
    if (condition) {temp = calculate();System.out.println(temp);
    }
    
  2. 避免未使用的变量:未使用的变量会浪费内存,且降低代码可读性。

  3. 初始化后再使用:尤其是局部变量,避免因未初始化导致的编译错误。

  4. 合理选择数据类型:根据实际需求选择合适的类型,避免内存浪费或精度问题。

    • 例如:存储年龄用byte即可(范围 - 128~127,足够表示人类年龄),无需用int
    • 存储货币金额时,避免用float/double(存在精度误差),推荐用BigDecimalint(以分为单位)。

八、课后习题

一、选择题(每题只有一个正确答案)

  1. 以下哪种 Java 变量声明中,正确的是( )
    A. int 1num = 10;
    B. String my-name = "test";
    C. double $price = 99.5;
    D. float value = 3.14;

  2. 关于 Java 局部变量的描述,错误的是( )
    A. 局部变量声明在方法或代码块中
    B. 局部变量必须初始化后才能使用
    C. 局部变量有默认值
    D. 局部变量的作用域仅限于声明它的代码块内

  3. 以下代码的运行结果是( )

public class Test {static int a = 10;int b = 20;public static void main(String[] args) {Test t = new Test();System.out.println(a + t.b);}
}

A. 编译错误
B. 30
C. 1020
D. 运行时错误

  1. 下列类型转换中,需要强制转换的是( )
    A. byte → short
    B. int → long
    C. double → float
    D. char → int

  2. 关于final修饰的变量,以下说法正确的是( )
    A. final变量必须在声明时初始化
    B. final变量的值可以被多次修改
    C. final局部变量可以先声明后初始化
    D. final只能修饰成员变量

二、填空题

  1. Java 中,基本数据类型char占用______字节,默认值是______。

  2. 变量根据作用域可分为局部变量、和______

  3. 以下代码中,变量x的数据类型是______,变量y的数据类型是______。

long x = 10000000000L;
float y = 3.14F;

4、执行以下代码后,变量result的值是______。

int a = 10;
double b = 3.5;
int result = (int)(a * b);

5、以下代码中,变量str是______(填 “基本类型” 或 “引用类型”)变量,它存储的是______。

String str = new String("Java");

答案及解析(做完后可对照):

  1. C
    解析:A 选项不能以数字开头;B 选项不能包含连字符;D 选项float赋值需加F/f

  2. C
    解析:局部变量没有默认值,必须显式初始化后才能使用。

  3. B
    解析:a是静态变量,可直接访问;b是实例变量,需通过对象访问,两者相加结果为 30。

  4. C
    解析:double范围大于float,从大范围到小范围需要强制转换。

  5. C
    解析:final变量可以先声明后初始化(空白 final 变量),但一旦赋值就不能修改,可修饰局部变量、成员变量等。

  6. 2;'\u0000'(空字符)

  7. 实例变量(成员变量);类变量(静态变量)

  8. longfloat

  9. 35
    解析:10 * 3.5 = 35.0,强制转换为int后截断小数部分,结果为 35。

  10. 引用类型;字符串对象在堆内存中的地址(引用)

http://www.dtcms.com/a/326094.html

相关文章:

  • Go 语言三大核心数据结构深度解析:数组、切片(Slice)与映射(Map)
  • Unity插件DOTween使用
  • 【GPT入门】第45课 无梯子,linux/win下载huggingface模型方法
  • 如何避免团队文件同步过程中版本信息的丢失?
  • GAI 与 Tesla 机器人的具体联动机制
  • 变频器与伺服系统的工作原理,干扰来源及治理方式
  • 软件测试关于搜索方面的测试用例
  • [AI 生成] kafka 面试题
  • 是否有必要使用 Oracle 向量数据库?
  • 【图像处理基石】UE输出渲染视频,有哪些画质相关的维度和标准可以参考?
  • OmniHuman:字节推出的AI项目,支持单张照片生成逼真全身动态视频
  • 不同FPGA开发板系统移植步骤
  • 《C++中 type_traits 的深入解析与应用》
  • 【Docker实战进阶】Docker 实战命令大全
  • “底层闭源 + Lua 脚本” 开发模式
  • 缺省路由的内容
  • 基于51单片机指纹识别管理门禁密码锁系统设计
  • “鱼书”深度学习进阶笔记(3)第四章
  • Spring Boot文件下载功能实现详解
  • Spring Boot 2.6.0+ 循环依赖问题及解决方案
  • C#高级语法_泛型
  • ClickHouse列式数据库的使用场景与基本优化手段
  • Jmeter使用第二节-接口测试(Mac版)
  • ​费马小定理​
  • jmeter 设置随机数
  • 爬虫与数据分析结合:中国大学排名案例学习报告
  • 【FAQ】Win11创建资源不足绕开微软账号登录
  • 在macOS上扫描192.168.1.0/24子网的所有IP地址
  • 深度学习和神经网络最基础的mlp,从最基础的开始讲
  • Springboot-vue 地图展现