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: 尝试将传入的字符串引用指向新字符串"xyz"
*changeArr: 遍历数组并将每个元素修改为原值加上索引号(如"aa"变为"aa0")
1.2 main方法的x有没有被改变?为什么?
答:没有改变。因为:
*Java采用值传递(pass-by-value)
*字符串是不可变对象
*changeStr方法中的x只是原始x的一个副本引用
*修改副本引用不会影响原始引用
1.3 main方法的args数组的内容有没有被改变?为什么?
答:有改变。因为:
*数组引用传递的是数组对象的引用副本
*副本引用和原始引用都指向同一个数组对象
*通过副本引用修改数组元素会影响原始数组
1.4 args数组中的值是从哪里来的?要怎么才能给他赋值。
答:args数组的值来自命令行参数。
赋值:
*命令行:java Main arg1 arg2 arg3
*在IDE中:在运行配置中设置程序参数
*通过其他数组赋值:args = new String[]{"a", "b", "c"}
2.数组相关问题
2.1 这段程序输出结果是什么?为什么?
int[] arr = new int[3];
arr[0] = 1; arr[1] = 1;
int[] arrX = arr; // arrX和arr指向同一个数组对象
arr[0] = 2; // 修改的是同一个数组
System.out.println(Arrays.toString(arr)); // [2, 1, 0]
System.out.println(Arrays.toString(arrX)); // [2, 1, 0]
答:输出结果都为[2,1,0],因为arrX = arr使得两个引用指向同一个数组对象。
2.2 字符串是不可变类,为什么可以对strArr[1]赋值"xx"。
答:字符串不可变指的是String对象本身内容不可变,strArr[1] = "xx"是修改数组引用,让数组的第二个元素指向新的String对象,原来的"bb"字符串对象没有被修改,仍然存在
3.二维数组问题
int[5][] arr = new int[5][]; // 第二维长度不确定,需要单独初始化
// 初始化第二维
arr[0] = new int[2];
arr[1] = new int[3];
arr[2] = new int[1];
arr[3] = new int[4];
arr[4] = new int[2];
// 使用foreach遍历
for (int[] innerArr : arr) {for (int num : innerArr) {System.out.print(num + " ");}System.out.println();
}
// 使用for循环
for (int i = 0; i < arr.length; i++) {for (int j = 0; j < arr[i].length; j++) {System.out.print(arr[i][j] + " ");}System.out.println();
}
4.类与对象问题
类与对象的区别是什么?
答:类:定义对象的属性和方法。对象:类的实例,具体的实体。
Math类有对象吗?
答:没有,Math类是final类,无法实例化对象。
String类的private属性和public方法
*private属性:private final char value[](存储字符数据)
*public方法:length(), charAt(), substring(), equals()等
设计原因:
比较安全,防止外部直接修改字符串内容,保证不可变性。
5.访问方法与封装性问题
setter/getter模式与封装性
为什么使用setter/getter而不是public属性:
控制访问:可以添加验证逻辑(如年龄不能为负数)
保持兼容性:可以在不改变接口的情况下修改内部实现
延迟初始化:可以在getter中实现懒加载
只读/只写控制:可以只提供getter或setter
与封装性的关系:setter/getter是封装性的具体体现,将数据隐藏,通过方法提供受控的访问。
6.初始化问题
初始化时机:
*声明时直接初始化
*构造方法中初始化
*初始化块中初始化
*懒加载(第一次使用时初始化)
初始化方法:
public class Example {//声明时初始化private String name = "default";//初始化块{age = 18;}//静态初始化块static {count = 0;}//构造方法中初始化public Example(String name) {this.name = name;}//懒加载private List<String> data;public List<String> getData() {if (data == null) {data = new ArrayList<>();}return data;}
}