JunRoss

 

JavaJava预习基础语法2、面向对象入门课前问题列表

Java 相关问题解答

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 changeStr与changeArr的功能各是什么?

答:
changeStr(String x): 该方法试图将传入的字符串引用指向新字符串"xyz",但由于Java字符串的不可变性和参数传递的按值调用特性,它不会改变原始字符串。
changeArr(String[] strs): 该方法遍历传入的字符串数组,为每个元素追加其索引值。

1.2 main方法的x有没有被改变?为什么?

答:
没有改变;Java采用按值调用,changeStr方法中的x只是原始x的一个副本,修改副本的引用不会影响原始变量,相当于(changeStr(String x)=“xyz”是扩大了一间x的房间且存放字符串xyz,由于它和main方法的房间都属于x,所以main方法房间中的字符串abc并没有改变)。

1.3 main方法的args数组的内容有没有被改变?为什么?

答:
有改变;数组是对象,changeArr方法接收的是数组引用的副本,但该副本仍指向原始数组对象,所以通过副本修改数组元素会直接影响原始数组。在 changeArr 方法中, strs[i] = strs[i] + "" + i 是直接修改数组内部的元素(即修改数组对象的内容),而非让副本指向新数组,由于原 args 和副本指向同一个数组,数组内容的修改会被 main 方法感知。最终输出格式为 [参数0+0, 参数1+1, 参数2+2, ...] 。若运行时传入参数 java Main a b c ,则输出为: [a0, b1, c2] ;若未传入任何参数,则输出 [] 。

1.4 args数组中的值是从哪里来的?要怎么才能给他赋值?

答:
值的来源:args 数组是Java程序运行时,通过命令行传入的参数,用于给main方法传递外部输入的字符串数据(若运行时未传入参数, args 是长度为0的空数组)。
赋值方式:命令行赋值(运行时传入):编译代码生成class文件(如 Main.class )后,在命令行执行 java Main 参数1 参数2 ... ,其中“参数1、参数2”会被自动存入 args 数组(如 java Main a b c ,则 args = {"a", "b", "c"} )。

2. 数组相关问题

对于下列程序:

2.1 这段程序输出结果是什么?为什么?
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,0]
[2,1,0]

原因:int[] arr = new int[3]是在堆内存中创建一个长度为3的int数组,数组内所有的元素初始值为0;arr[0] = 1、arr[1] = 1是修改数组的第0和第1个元素为1;int[] arrX = arr,这不是创建新的数组,而是将arrX变量指向arr所指向的同一个数组对象,此时arr和arrX两个变量都引用同一个数组对象;arr[0] = 2,然后通过arr引用修改数组的第0个元素为2,由于arrX
指向同一个数组,所以这个修改也同时对arrX奏效,因此两个数组都为同一个数组[2,1,0]。

2.2 字符串不可变,为什么可以对strArr[1]赋值"xx"?

String[] strArr = {"aa","bb","cc"};
strArr[1] = "xx";
System.out.println(Arrays.toString(strArr));

答:
原因:字符串不可变指的是字符串对象的内容不可变(例如,无法将"bb"改为"xx"),但数组元素是引用变量,可以重新指向新的字符串对象(此处将strArr[1]从指向"bb"改为指向"xx";原始字符串"bb"未被修改,而是被新字符串"xx"替换。

3. 二维数组与遍历

定义与遍历int[5][]

int[][] twoDimArr = new int[5][]; // 第二维长度未定

// 初始化第二维
twoDimArr[0] = new int[3];
twoDimArr[1] = new int[2];
twoDimArr[2] = new int[4];
twoDimArr[3] = new int[1];
twoDimArr[4] = new int[5];

// 使用嵌套循环遍历
for (int i = 0; i < twoDimArr.length; i++) {
    for (int j = 0; j < twoDimArr[i].length; j++) {
        System.out.print(twoDimArr[i][j] + " ");
    }
    System.out.println();
}

// 或使用foreach
for (int[] row : twoDimArr) {
    for (int num : row) {
        System.out.print(num + " ");
    }
    System.out.println();
}

4.类与对象的区别是什么? Math类有对象吗?String类有什么属性是private的,有什么方法是public的,为什么这样设计(尝试举两例说明)?

答:
4.1
类与对象的区别
类:模板/蓝图,定义对象的属性和行为(例如:String类)。
对象:类的实例,具有具体状态(例如:String s = "hello")。
4.2
Math类有对象吗?
没有。Math类的构造方法是私有的,所有方法和属性都是静态的,因此无需创建对象即可使用。
4.3
String类的private属性和public方法:
private属性:
-private final byte[] value:存储字符串内容(Java 9后改用byte[]优化)。
-private int hash:缓存哈希值。
public方法:
-public int length():获取长度(不暴露内部数组)。
-public char charAt(int index):安全访问字符(避免越界)。

5.将类的属性设置为public可以方便其他类访问,但为什么Java中普遍使用setter/getter模式对对象的属性进行访问呢?这与封装性又有什么关系?

答:
5.1
为什么普遍使用setter/getter?
1. 控制访问:可在setter中添加验证逻辑(例如:年龄不能为负数)。
2. 解耦:允许修改内部实现而不影响外部代码(例如:将存储方式从数组改为链表)。
3. 只读/只写:通过只提供getter或setter实现。
4. 线程安全:可在方法中添加同步机制。

5.2与封装性的关系
封装性要求隐藏对象内部状态,仅通过可控的方法暴露操作。setter/getter是实现封装的核心手段,确保数据安全性和一致性。

6. 对象的属性可在什么时候进行初始化?都有哪些进行初始化的办法?

初始化时机和方法

  1. 默认初始化(声明时默认值,如int为0)。
  2. 显式初始化(声明时赋值,如private int age = 10;)。
  3. 构造块初始化({ age = 20; })。
  4. 构造函数初始化(public Person() { age = 30; })。
  5. 静态初始化块(仅静态属性,static { ... })。
  6. 通过setter方法初始化(对象创建后赋值)。

posted on 2025-09-15 20:20  00后留声机  阅读(6)  评论(0)    收藏  举报

导航