Java 核心概念深度解析:方法、数组与类
一、方法参数传递机制
示例代码分析
import java.util.Arrays;public class Main {static void changeStr(String x) {x = "xyz";}static void changeArr(String[] strs) {for (int i = 0; i < strs.length; i++) {strs[i] = strs[i] + "" + i;}}public static void main(String[] args) { String x = "abc";changeStr(x);System.out.println(x); // 输出:abcchangeArr(args);System.out.println(Arrays.toString(args));}
}
1.1 方法功能解析
- changeStr方法:接收String参数并尝试修改其值,但实际无法改变原始变量
- changeArr方法:接收String数组参数并修改其元素内容,能够改变原始数组
1.2 字符串参数为何不变?
Java采用值传递机制:
- 基本类型:传递值的副本
- 引用类型:传递引用的副本(而非对象本身)
当调用changeStr(x)
时:
- 传递的是x引用的副本(指向"abc")
- 方法内
x = "xyz"
只是让副本指向新对象 - 原始x的引用保持不变,仍指向"abc"
1.3 数组参数为何改变?
- 传递的是数组引用的副本
- 副本和原始引用指向同一个数组对象
- 通过引用修改对象内容,会影响所有指向该对象的引用
1.4 args数组的赋值方式
- 来源:命令行参数
- 赋值方式:运行程序时在命令行指定
java Main hello world 123
此时args数组内容为:["hello", "world", "123"]
二、数组特性深入解析
2.1 数组引用传递示例
import java.util.Arrays;public class ArrayTest {public static void main(String[] args) {int[] arr = new int[3];arr[0] = 1; arr[1] = 1;int[] arrX = arr; // 引用赋值arr[0] = 2; // 修改原始数组System.out.println(Arrays.toString(arr)); // [2, 1, 0]System.out.println(Arrays.toString(arrX)); // [2, 1, 0]}
}
关键点:arrX = arr
使两个变量指向同一数组对象,任一变量修改都会影响另一变量。
2.2 字符串数组的"修改"原理
String[] strArr = {"aa","bb","cc"};
strArr[1] = "xx"; // 看似修改字符串,实为修改引用
- 字符串不可变:String对象内容创建后不可更改
- 数组元素可重新赋值:改变的是引用指向,而非字符串内容本身
2.3 二维数组的灵活结构
int[][] arr = new int[5][]; // 只定义第一维长度// 第二维可定义不同长度
arr[0] = new int[2]; // 长度2
arr[1] = new int[3]; // 长度3
// ...其余类似// 遍历不规则二维数组
for (int i = 0; i < arr.length; i++) {if (arr[i] != null) {for (int j = 0; j < arr[i].length; j++) {System.out.print(arr[i][j] + " ");}System.out.println();}
}
三、类与对象核心概念
3.1 类与对象的区别
类别 | 定义 | 示例 |
---|---|---|
类 | 对象的蓝图/模板 | class Car { ... } |
对象 | 类的具体实例 | Car myCar = new Car(); |
Math类的特殊性:
- 构造方法私有化(
private Math() {}
) - 所有方法均为静态方法
- 无需创建实例,直接通过类名调用:
Math.random()
3.2 String类的封装设计
// 内部实现关键代码示意
public final class String {private final char value[]; // 私有最终字符数组private int hash; // 缓存哈希值// 公共访问方法public int length() {return value.length;}public char charAt(int index) {if (index < 0 || index >= value.length) {throw new StringIndexOutOfBoundsException(index);}return value[index];}
}
设计优势:
- 不可变性保障:final修饰防止继承修改,final数组成员防止数组引用被修改
- 安全性:防止外部直接修改内部数据
- 线程安全:不可变对象天然线程安全
- 性能优化:哈希值缓存等优化手段
3.3 Setter/Getter模式的价值
传统直接访问的问题:
public class Person {public int age; // 直接公共访问
}// 外部可能设置非法值
person.age = -100; // 逻辑错误但无法阻止
Setter/Getter模式优势:
public class Person {private int age;public void setAge(int age) {if (age >= 0 && age <= 150) { // 数据验证this.age = age;} else {throw new IllegalArgumentException("无效年龄");}}public int getAge() {return age;}
}
3.4 对象属性初始化时机
初始化方式 | 执行时机 | 示例 |
---|---|---|
声明时初始化 | 类加载时 | private String name = "默认值"; |
实例初始化块 | 构造函数前 | { age = 18; } |
构造方法初始化 | 对象创建时 | Person() { name = "张三"; } |
Setter方法初始化 | 运行时动态设置 | person.setName("李四"); |
四、封装性与作用域
4.1 访问修饰符的作用范围
修饰符 | 同类 | 同包 | 子类 | 其他包 |
---|---|---|---|---|
private | ✓ | ✗ | ✗ | ✗ |
default | ✓ | ✓ | ✗ | ✗ |
protected | ✓ | ✓ | ✓ | ✗ |
public | ✓ | ✓ | ✓ | ✓ |
4.2 封装性的实际价值
- 数据保护:防止意外修改关键数据
- 接口稳定性:内部实现可变更而不影响外部调用
- 模块化设计:明确各模块的职责边界
- 代码可维护性:降低代码耦合度,便于调试和测试
总结
Java的核心概念体现了其设计哲学:简单性、安全性和可维护性。理解这些基础概念的关键点:
- 方法参数传递:始终是值传递,区别在于传递的是基本值还是引用值
- 数组特性:引用类型,需要区分引用本身和引用指向的对象
- 字符串特殊性:不可变对象,修改操作实际创建新对象
- 类与对象:类是模板,对象是实例,封装是核心设计原则
- 封装性:通过访问控制实现信息隐藏,提高代码质量
掌握这些基础概念,不仅能够编写正确的Java代码,更能理解Java语言的设计思想,为深入学习高级特性和框架打下坚实基础。