66 Java final 修饰基本类型变量和引用类型变量的区别

本文通过具体示例介绍了Java中final修饰符的使用方法,特别是针对基本类型与引用类型的区别。展示了final修饰数组变量及Person对象时的行为差异,并解释了为何可以修改数组元素或对象状态,但不能重新赋值。
package new20140418;


import java.util.Arrays;



class Person {
	private int age;

	public Person() {
	};

	// 有参数构造器
	public Person(int age) {
		this.age = age;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

}
/**
 * final 修饰基本类型变量和引用类型变量的区别
 * 
 * @author x
 * 
 */
public class Test5 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		// final 修饰数组变量,iArr时一个引用变量
		final int[] iArr = { 5, 6, 12, 9 };
		System.out.println(iArr.toString());
		// 对数组元素进行排序,合法
		Arrays.sort(iArr);
		System.out.println(Arrays.toString(iArr));

		// 对数组元素赋值,合法
		iArr[2] = -10;
		System.out.println(Arrays.toString(iArr));

		// 对iArr重新赋值,非法
		// iArr=null;
		
		//final 修饰Person变量,p是一个引用变量
		final Person p=new Person(45);
		
		//改变Person 对象的age Field 合法
		p.setAge(46);
		System.out.println(p.getAge());
		
		

	}

	

}

<think>我们正在讨论Java中静态变量final关键字的关系,特别是声明静态变量时使用final关键字是否会使其成为静态常量。 根据引用[1][2][3]: - final修饰变量时,该变量成为常量,只能赋值一次。 - static修饰变量属于类,在类加载时初始化。 - 当同时使用staticfinal修饰一个变量时,这个变量就是静态常量(类常量),它在整个类中只有一份,且不能被修改。 因此,答案是肯定的:在Java中,使用static final修饰变量就是静态常量。 详细解释: 1. **静态常量的特性**: - **唯一性**:由于static修饰,该变量内存中只有一份,属于类而不是实例。 - **不可变性**:由于final修饰,一旦赋值后,其值不可更改。 - **初始化要求**:必须在声明时赋值,或者在静态代码块中赋值(因为final要求必须初始化,且static要求初始化在类加载时完成)。 2. **初始化方式**: - 声明时直接赋值(推荐): ```java public static final double PI = 3.14159; ``` - 在静态代码块中赋值(适合需要计算的情况): ```java public static final double PI; static { PI = 3.14159; // 复杂的计算可以在这里进行 } ``` 3. **与实例常量的区别**: - 实例常量(只有final,没有static):每个对象都有一份,且必须在构造方法或实例初始化块中初始化。 - 静态常量(static final):整个类只有一份,在类加载时初始化。 4. **访问方式**: - 通过类名直接访问(推荐): ```java double circleArea = Math.PI * radius * radius; // Math.PI是静态常量 ``` - 也可以通过对象访问(但不推荐,因为容易引起混淆)。 5. **命名规范**: - 静态常量通常使用全大写字母,单词间用下划线分隔,例如:`MAX_VALUE`。 6. **使用场景**: - 定义数学常数(如PI)。 - 配置参数(如最大连接数)。 - 枚举值的替代(在枚举类型出现之前)。 引用[1][3]都明确提到:`static final`修饰的成员变量在同一类不同对象中不能改变,即它是静态常量[^1][^3]。 示例代码(来自引用[1]): ```java public class TestDemo { final static int m = 11; // 声明时直接赋值的静态常量 final static int n; // 空白静态常量,必须在静态块中初始化 static { n = 66; // 正确,在静态块中初始化空白静态常量 } } ``` 注意:如果静态常量(static final)在声明时未赋值(即空白静态常量),则必须在静态代码块中赋值,且只能赋值一次。在静态代码块之外赋值会导致编译错误。 总结:在Java中,声明静态变量时使用final关键字会使其成为静态常量,具有全局唯一性不可变性。 §§相关问题§§ 1. 静态常量实例常量在内存分配上有何不同? 2. 在Java中,如何确保静态常量的线程安全性? 3. 静态常量在类加载过程中的初始化顺序是怎样的?</think>### Java中静态变量与`final`关键字的关系 在Java中,声明静态变量时使用`final`关键字**会使其成为静态常量**。以下是关键点解析: #### 1. **静态常量的定义** - **`static final`组合**: - `static`表示变量属于类(而非实例),在类加载时初始化,内存中只有一份副本。 - `final`表示变量值不可修改(常量)。 两者结合即**静态常量**,例如: ```java public static final double PI = 3.14159; // 静态常量 ``` #### 2. **静态常量的特性** - **不可变性**: `final`确保值只能赋值一次(编译期或类加载时),后续修改会导致编译错误[^1][^2]。 - **全局唯一性**: `static`保证所有实例共享同一内存地址,值在类加载时确定[^3]。 - **初始化要求**: - 声明时直接赋值(推荐): ```java static final int MAX_VALUE = 100; ``` - 或在**静态代码块**中赋值(复杂初始化时): ```java static final int MAX_VALUE; static { MAX_VALUE = calculateMax(); // 复杂计算 } ``` 若未初始化,编译报错(违反`final`规则)[^1]。 #### 3. **与普通静态变量区别** | **特性** | **普通静态变量** | **静态常量 (`static final`)** | |------------------|------------------------|--------------------------------| | 值是否可修改 | 是(可通过方法修改) | 否(编译错误) | | 初始化时机 | 类加载时(可延迟赋值) | 类加载时**必须完成**赋值 | | 线程安全性 | 需同步控制 | 天然线程安全(不可变) | | 典型用途 | 全局计数器、配置参数 | 数学常数、枚举值、配置常量 | #### 4. **代码示例 ```java public class Constants { // 静态常量(声明时赋值) public static final String APP_NAME = "MyApp"; // 静态常量(静态块中赋值) public static final int MAX_USERS; static { MAX_USERS = loadConfig(); // 从配置文件读取 } // 错误示例:未初始化 final 变量 // static final int UNINITIALIZED; // 编译报错 } ``` #### 5. **设计意义** - **安全性**:防止意外修改(如`Math.PI`)。 - **可读性**:明确标识常量(命名规范:全大写+下划线)。 - **性能优化**:编译器可能内联常量值(直接替换为字面量)[^3]。 > **总结**: > 在Java中,`static final`修饰变量是**静态常量**,需在类加载时完成初始化且不可修改。它是定义全局常量的标准方式,如`Integer.MAX_VALUE`[^1][^3]。 --- ### 相关问题 1. **静态常量实例常量在内存分配上有何不同?** (静态常量属于类,实例常量属于对象,内存分配位置不同) 2. **在Java中,如何确保静态常量的线程安全性?** (不可变性天然线程安全,但初始化过程需注意竞态条件) 3. **静态常量在类加载过程中的初始化顺序是怎样的?** (与静态变量相同,按代码顺序初始化)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值