一、方法相关问题
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";
changeArr的功能:将String数组中的每个元素后面都加上序号;
1.2 main方法的x有没有被改变?为什么?
没有;
原因:根据Java特性,changeStr只是创建了一个新的空间用来存放“xyz”,原来x并没有被改变,用鼠标光标指向main方法中的x可以看到它仍然指向原来值;
1.3 main方法的args数组的内容有没有被改变?为什么?
有;
原因:不能改变数值,但是可以改变数组的引用,main方法中的args数组在changeArr中改变了引用对象,所以内容被改变;
1.4 args数组中的值是从哪里来的?要怎么才能给他赋值。
可以从控制台或者用命令行输入;
赋值要用命令行传参;
二、数组相关问题
对于如下程序
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 这段程序输出结果是什么?为什么?
arr[]->[2 1 0]
arrrX[]->[2 1 0]
原因:arrX指向的对象是arr,所以当arr指向改变时,arrX的指向也会改变;
String [ ] strArr = { "aa" , "bb" , "cc" } ;
strArr[ 1 ] = "xx" ;
System . out. println ( Arrays . toString ( strArr) ) ;
2.2 字符串是不可变类,为什么可以对strArr[1]赋值"xx"。
对其赋值改变的不是strArr中的值而是其引用,字符串是不可变类,意味着不能够改变它的值,但是可以改变它的引用;
3.使用int[5][]定义一个二维数组,其第二维到底有多长?尝试补全代码,然后使用foreach获其他循环方法遍历这个二维数组?
无法确定;
import java. util. Scanner ;
public class Main {
public static void main ( String [ ] args) {
Scanner sc = new Scanner ( System . in) ;
int a[ ] [ ] = new int [ 5 ] [ ] ;
for ( int i = 0 ; i < a. length; i++ ) {
a[ i] = new int [ 5 ] ;
System . out. println ( "请输入第 " + ( i + 1 ) + " 行的5个整数:" ) ;
for ( int j = 0 ; j < a[ i] . length; j++ ) {
a[ i] [ j] = sc. nextInt ( ) ;
}
System . out. println ( "第 " + ( i + 1 ) + " 行的整数是:" ) ;
for ( int j : a[ i] ) {
System . out. print ( j + " " ) ;
}
System . out. println ( ) ;
}
sc. close ( ) ;
}
}
4.类与对象的区别是什么? Math类有对象吗?String类有什么属性是private的,有什么方法是public的,为什么这样设计(尝试举两例说明)?
4.1 类与对象的区别
类:类是抽象的,它本身不占用内存空间,只是用来描述对象的行为和状态。类中定义了构造方法、成员变量和方法;
对象:对象是类的实例,是类的一个具体存在,它占用内存空间,有实际的值和状态。通过类可以创建多个对象,每个对象都是类的一个具体实现,但可以有不同的属性值;
4.2 Math类没有对象。Math类是一个工具类,它包含了一系列静态方法和常量,用于执行基本的数学运算,如指数、对数、平方根、三角函数等,可以直接通过类名调用,而不需要创建Math类的对象;
4.3 private属性与public属性
private属性:String类用于管理字符串的存储和状态。如,String类可能使用字符数组(char[])来存储字符串的字符,是私有的,外部无法直接访问。这是利用了Java的封装性;
public属性:public int length():返回字符串的长度。public String substring(int beginIndex, int endIndex):返回字符串的一个子字符串,从beginIndex(包含)到endIndex(不包含)。
原因:private属性被封装起来,外部不能直接访问,只能通过公有方法进行间接操作,这有助于保护数据的安全性和完整性。public属性提供了丰富的字符串操作功能,可以方便地进行字符串的拼接、查找、替换等操作,提高了代码的灵活性和可重用性。
5.将类的属性设置为public可以方便其他类访问,但为什么Java中普遍使用setter/getter模式对对象的属性进行访问呢?这与封装性又有什么关系?
原因:尽管将类的属性设置为public可以方便其他类直接访问,但这种做法破坏了封装性,使得对象内部的数据变得不安全、易于被误修改,并且降低了代码的灵活性和可维护性。因此,在Java中普遍使用setter/getter模式来访问对象的属性;
6.对象的属性可在什么时候进行初始化?都有哪些进行初始化的办法?
6.1
声明时;构造方法时;初始化块时;通过Setter方法初始化时;链式构造方法时;通过Builder模式初始化时;
6.2 初始化方式
直接赋值:在声明属性时直接为其指定一个初始值。
构造方法:在构造方法中为属性赋值。
初始化块:在静态或非静态初始化块中为属性赋值。
Setter方法:通过调用对象的Setter方法来设置属性的值。
链式构造方法:在构造方法中调用其他构造方法来初始化对象。
Builder模式:使用Builder类的链式方法来设置属性,并最终构建对象。
7.进阶(可选):尝试使用作用域来说明封装性。
限制访问:
封装性的一个核心目标是限制对对象内部数据的直接访问,以保护数据的安全性和完整性。这通常是通过将对象的属性声明为private或protected来实现的。这种限制访问的能力正是通过作用域来实现的。
提供接口:
封装性不仅限制了外部对对象内部数据的直接访问,还通过提供public的getter和setter方法来为外部代码提供访问和修改对象属性的途径。这些public方法定义了对象与外部环境之间的接口。由于这些方法是公有的,因此它们在整个类或包的作用域内都是可见的。这种通过公有方法提供接口的方式,既保护了内部数据的安全,又提供了灵活的访问机制。
隐藏细节:
封装性还强调隐藏对象的内部实现细节,只通过接口与外部交互。这有助于降低系统的耦合度,提高代码的可维护性和可扩展性。通过作用域的控制,可以将对象的内部实现与外部隔离,只暴露必要的接口给外部使用。这样,即使内部实现发生变化,只要接口保持不变,就不会影响到外部代码。