# java基础语法 2 面向对象入门
方法相关问题,如下代码:
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);
changeArr(args);
System.out.println(Arrays.toString(args));
}
}
1.1 changeStr 与 changeArr 的功能各是什么?
1.2 main 方法的x有没有被改变?为什么?
1.3 main 方法的 args 数组的内容有没有被改变?为什么?
**1.4 args 数组中的值是从哪里来的?要怎么才能给他赋值。
1.1 : changeStr 方法:接收一个 String 类型的参数 x ,并尝试将其赋值为 "xyz" 。但由于 Java 中字符串是不可变的,且参数传递为值传递,该方法无法改变外部实际传入的字符串变量。
changeArr 方法:接收一个 String[] 数组参数 strs ,遍历数组并修改每个元素的值(在原字符串后拼接当前索引)。由于数组是引用类型,该方法会直接修改原数组的内容。
1.2 : 没有被改变,输出结果仍然是 "abc" 。Java 中方法参数传递是值传递。当调用 changeStr(x) 时,实际传递的是 x 的副本(即字符串 "abc" 的引用地址)。在 changeStr 方法中, x = "xyz" 只是将这个副本指向了新的字符串,而原 main 方法中的x仍然指向原来的 "abc" ,因此不会被改变。
1.3 :被改变了。
原因:
数组是引用类型。当调用 changeArr(args) 时,传递的是数组 args 的引用地址(副本),但这个副本和原 args 指向同一块内存空间。在 changeArr 方法中,通过 strs[i] = ...修改数组元素时,实际是在操作这块内存中的数据,因此原 main 方法中的 args 数组内容会被同步修改。
1.4 :来源: args 数组是 main 方法的参数,用于接收程序运行时从命令行传入的参数。例如通过 java Main a b c 运行程序时, args 会被初始化为["a", "b", "c"]。命令行传入(最常用):编译后运行程序时,在类名后添加参数,用空格分隔。
数组相关问题,对于如下程序
int[] arr = new int[3];
arr[0] = 1; arr[1] = 1;
int[] arrX = arr;
arr[0] = 2;
System.out.println(Arrays.toString(arr));
System.out.println(Arrays.toString(arrX));
2.1 这段程序输出结果是什么?为什么?
String[] strArr = {"aa","bb","cc"};
strArr[1] = "xx";
System.out.println(Arrays.toString(strArr));
2.2 字符串是不可变类,为什么可以对strArr[1]赋值"xx"。
2.1 :输出结果: [2, 1, 0] 下一行 [2, 1, 0]
原因:
在 Java 中,数组属于引用数据类型。当执行 int[] arrX = arr ; 时,arrX 和 arr 指向同一块内存地址(即引用同一个数组对象)。
后续修改 arr[0] = 2 时,实际是修改了该内存地址中数组的第一个元素值;
由于 arrX 与 arr 指向同一个数组,因此打印两者的内容时,会显示相同的结果。
2.2 :字符串的 “不可变” 是指字符串对象本身的内容不可修改(例如 "bb" 一旦创建,其字符序列不能被改变)。但数组 strArr 中存储的是字符串对象的引用(地址),而非字符串本身。
当执行 strArr[1] = "xx" 时:并没有修改原字符串 "bb" 的内容(它依然存在于内存中);只是将数组索引 1 位置的引用,从指向 "bb" 改为指向新的字符串对象 "xx"。因此,这一操作与字符串的不可变性并不冲突,本质是修改了数组中存储的引用地址。
使用int[5][]定义一个二维数组,其第二维到底有多长?尝试补全代码,然后使用foreach获其他循环方法遍历这个二维数组?
int[5][] 定义了一个包含 5 个元素的二维数组,但第二维(每个子数组)的长度是不确定的。这是一个「不规则二维数组」,每个子数组可以有不同的长度,甚至可以为 null(未初始化)
代码展示:
import java.util.Arrays;
public class SimplifiedTwoDimensionalArray {
public static void main(String[] args) {
// 初始化二维数组并直接赋值
int[][] arr = {
{10, 20}, // 长度为2的子数组
{0, 0, 30}, // 长度为3的子数组
{0}, // 长度为1的子数组
null, // 未初始化的子数组
{40, 0, 0, 0} // 长度为4的子数组
};
System.out.println("数组整体结构:" + Arrays.deepToString(arr) + "\n---------------------");
// 合并遍历逻辑,使用一种循环方式展示
System.out.println("foreach遍历结果:");
for (int[] subArray : arr) {
if (subArray == null) {
System.out.println("子数组为null");
} else {
for (int num : subArray) {
System.out.print(num + " ");
}
System.out.println();
}
}
}
}
类与对象的区别是什么? Math 类有对象吗? String 类有什么属性是 private 的,有什么方法是 public 的,为什么这样设计?
类与对象的区别
本质不同:类:是一个抽象的模板,定义了对象的属性(数据)和方法(行为),描述了一类事物的共同特征。例如,“汽车类” 定义了所有汽车都有的属性(颜色、型号)和方法(行驶、刹车)。对象:是类的具体实例,是真实存在的个体。例如,“我家的红色特斯拉 Model 3” 是 “汽车类” 的一个对象。
没有, Math 类是 Java 中的一个工具类,其构造方法被声明为 private (私有),且所有方法和属性都是 static (静态)的。
String 类是 Java 中最常用的类之一,其设计遵循 “封装” 原则:用 private 属性保护数据,用 public 方法提供安全的操作接口。
将类的属性设置为 public 可以方便其他类访问,但为什么 Java 中普遍使用 setter/getter 模式对对象的属性进行访问呢?这与封装性又有什么关系?
setter/getter 模式的核心作用
控制访问权限 public 属性允许外部任意读写,而 setter/getter 可以精细化控制:只提供 getter 不提供 setter :属性变为 “只读”(如 String 的 length ()方法,本质是获取 value 数组的长度,但不允许修改),还有隐藏实现细节和支持懒加载与缓存等作用。
与封装性的关系:

浙公网安备 33010602011771号