预习2

1. 方法相关问题

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 changeStrchangeArr的功能各是什么?
1.2 main方法的x有没有被改变?为什么?
1.3 main方法的args数组的内容有没有被改变?为什么?
1.4 args数组中的值是从哪里来的?要怎么才能给他赋值。

1. 关于第一段代码的问题

1.1

  • changeStr 方法:将传入的 String 类型参数 x 赋值为 "xyz",但由于 String 是不可变类,所以这里只是在方法内改变了局部变量 x 的引用。
  • changeArr 方法:遍历传入的 String 数组 strs,将数组中的每个元素与对应的索引值拼接后重新赋值给该元素。

1.2

main 方法中的 x 没有被改变,因为 String 是不可变对象,在 changeStr 方法中,只是将方法内的局部变量 x 指向了新的字符串 "xyz",而 main 方法中的 x 仍然指向原来的 "abc"

1.3

main 方法中的 args 数组的内容被改变了,因为数组是引用类型,changeArr 方法接收到的是 args 数组的引用,在方法内对数组元素的修改会影响到原数组。

1.4

args 数组中的值是从程序运行时的命令行参数传来的,如果要给它赋值,可以在运行 Java 程序时,在命令行中输入参数,例如 java Main 参数1 参数2 参数3,这些参数就会被传入 args 数组。

2. 数组相关问题

对于如下程序

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"
3. 使用int[5][]定义一个二维数组,其第二维到底有多长?尝试补全代码,然后使用foreach获其他循环方法遍历这个二维数组?
4. 类与对象的区别是什么?Math类有对象吗?String类有什么属性是private的,有什么方法是public的,为什么这样设计(尝试举两例说明)?
5. 将类的属性设置为public可以方便其他类访问,但为什么Java中普遍使用setter/getter模式对对象的属性进行访问呢?这与封装性又有什么关系?

2. 数组相关问题

2.1

输出结果都是 [2, 1]。因为 arrX 引用了 arr 数组,它们指向的是同一个数组对象,所以当 arr[0] 被赋值为 2 时,arrX 所指向的数组内容也会相应改变。

2.2

字符串是不可变类,指的是字符串对象本身的内容不可变,但是 strArr 是字符串数组,strArr[1] 存储的是字符串对象的引用。给 strArr[1] 赋值 "xx",是让 strArr[1] 这个引用指向了新的字符串对象 "xx",而不是改变原来字符串对象的内容。

3. 二维数组问题

int[5][] 定义的是一个二维数组,它有 5 个一维数组的引用,但第二维(每个一维数组)的长度没有确定,可以在后续代码中分别为每个一维数组指定长度,例如:

int[][] twoDArr = new int[5][];
twoDArr[0] = new int[3];
twoDArr[1] = new int[4];
// 其他一维数组可类似赋值
// 使用 for 循环遍历
for (int i = 0; i < twoDArr.length; i++) {
    if (twoDArr[i] != null) {
        for (int j = 0; j < twoDArr[i].length; j++) {
            System.out.print(twoDArr[i][j] + " ");
        }
        System.out.println();
    }
}
// 使用 foreach 遍历
for (int[] arr : twoDArr) {
    if (arr != null) {
        for (int num : arr) {
            System.out.print(num + " ");
        }
        System.out.println();
    }
}

4. 类与对象等问题

  • 类是对象的模板,是对事物的抽象描述;对象是类的实例,是具体存在的个体。
  • Math 类没有对象,它的方法都是静态方法,通过类名直接调用。
  • String 类中,value(存储字符串字符的数组)等属性是 private 的,length()(获取字符串长度)、charAt(int index)(获取指定索引的字符)等方法是 public 的。这样设计是为了封装,保护内部数据不被随意修改,同时提供公共方法供外部安全地操作字符串。

5. setter/getter 相关问题

使用 setter/getter 模式,能在设置和获取属性值时添加逻辑(如数据验证等),更好地实现封装性,隐藏类的内部实现细节,只对外提供安全的访问接口,防止外部直接操作属性可能带来的不合法数据等问题。

6. 对象属性初始化问题

对象的属性可以在以下时候初始化:

  • 声明属性时直接赋值,如 private int age = 18;
  • 在构造方法中初始化。
  • 使用初始化块(静态初始化块和实例初始化块)进行初始化。

7. 封装性与作用域

作用域(如 privatepublic 等访问修饰符)用于限制类的成员(属性和方法等)的访问范围。private 修饰的成员只能在类内部访问,public 修饰的成员可以在任何地方访问。通过这种作用域的限制,实现了封装性,将类的内部细节隐藏起来,只暴露必要的公共接口供外部使用,保证了类的安全性和可维护性。

posted @ 2025-09-15 00:13  Jbuckle  阅读(1)  评论(0)    收藏  举报