习题解答chapter02
1. 对象与对象引用的区别是什么?
创建案例代码:
public class Study{
// 默认构造方法
public Study{
}
}
对象创建操作
Study temp = new Study();
语句解读:
- 左边的“Study temp”创建了一个Study类引用变量,它存放在栈空间中,储存这指向对象的地址,也就是指向Study对象的对象引用。
- 右边的“new Study”,是以Study类为模版,在堆空间创建类一个Study的对象。
- 语句等价与下面分解语句:
Study temp; // 创建对象引用
temp = /*将对象引用指向对象*/ new Study(); // 创建对象
- 一个对象引用可以指向一个对象或者不指向对象;一个对象可以被一个或多个对象引用(同时)引用
// 一个对象引用指向一个对象
Study temp;
temp = new Study();
// 一个对象引用被创建,但是并不指向任何一个对象
Study temp;
// 一个对象被一个对象引用所引用
Study temp;
temp = new Study();
// 一个对象被多个对象引用同时引用
Study temp1, temp2, temp3;
temp1 = new Study();
temp2 = temp1;
temp3 = temp2;
2. 对象作为参数传递的特点是什么?
对象是引用传递,当对象作为参数传递时,传递的是对象的地址,也就是说并没有创建新的对象。
class IntClass {
int value;
}
public class RunIntClass {
public static void modifyValue(IntClass s, int val) {// s=a,多个对象引用指向一个对象
s.value = val;
}
//上述结束后,s随着栈空间而被释放,但是value已经被改变且存储在堆空间,并且a依旧指向对象空间
public static void main(String args[]) {
IntClass a = new IntClass();
modifyValue(a, 8); // 将a传递给s
System.out.println(a.value); // value不是默认的0,变成了8
}
}
3. 对象初始化的顺序是什么?
非继承情况下对象初始化顺序
public class Test {
public static void main(String[] args) {
new Order();
}
}
class Order{
AAA s = new AAA("成员变量");
static AAA a = new AAA("静态成员变量");
{
System.out.println("初始化块");
}
static{
System.out.println("静态初始化块");
}
Order(){
System.out.println("构造方法");
}
}
class AAA{
public AAA(String str){
System.out.println(str);
}
}
输出结果:
静态成员变量
静态初始化块
成员变量
初始化块
构造方法
结论:非继承情况下实例化一个对象,构造的先后顺序是,静态成员变量>静态初始化块>成员变量>初始化块>构造方法
一般顺序为 先静态,后非静态,先变量,后初始化块,再是构造方法
继承情况下对象初始化顺序
public class Test2 {
public static void main(String[] args) {
new Son();
}
}
class Parent{
{
System.out.println("parent中的初始化块");
}
static{
System.out.println("parent中static初始化块");
}
public Parent(){
System.out.println("parent构造方法");
}
}
class Son extends Parent{
{
System.out.println("son中的初始化块");
}
static{
System.out.println("son中的static初始化块");
}
public Son(){
System.out.println("son构造方法");
}
}
输出结果:
parent中static初始化块
son中的static初始化块
parent中的初始化块
parent构造方法
son中的初始化块
son构造方法
- 总结:属性、方法、构造方法和自由块都是类中的成员,在创建类的对象时,类中各成员的执行顺序:
1. 父类静态成员和静态初始化快,按在代码中出现的顺序依次执行。
2. 子类静态成员和静态初始化块,按在代码中出现的顺序依次执行。
3. 父类的实例成员和实例初始化块,按在代码中出现的顺序依次执行。
4. 执行父类的构造方法。
5. 子类实例成员和实例初始化块,按在代码中出现的顺序依次执行。
6. 执行子类的构造方法。
4. 类的static字段与非static字段的区别是什么?什么情况下应该使用static修饰符?
静态对象 | 非静态对象 |
---|---|
类共同拥有 | 类独立拥有 |
内存空间上是固定的 | 空间在各个附属类里面分配 |
先分配静态对象空间 | 继而再对非静态对象分配空间 |
- 类中被static修饰的域变量专属于类,并不复制到对象中,也就是说是全局唯一的,任何一次修改都影响到全局。它被保存在类的内存区(堆中)的公共存储单元中,而不是保存在某个对象的内存区。
例证类的静态属性可以被类、多个对象引用访问,利用此性质对类的对象的个数计数:
public class staticchapter {
public static class Test {
static int i = 0;
Test(){
i++;
}
public int getI(){
System.out.println(i);
return i;
}
}
public static void main(String args[]){
Test temp1, temp2, temp3, temp4;
temp1 = new Test();
System.out.println("temp1: " + temp1.getI());
temp2 = temp1;
System.out.println("temp2: " + temp2.getI());
temp3 = temp1;
temp4 = temp1;
Test temp5 = new Test();
System.out.println("temp3: " + temp3.getI());
System.out.println("temp4: " + temp4.getI());
temp5 = new Test();
System.out.println("temp5: " + temp5.getI());
}
}
输出结果:
第1次
temp1: 1
第1次
temp2: 1
第2次
temp3: 2
第2次
temp4: 2
第3次
temp5: 3
- 静态代码块:一个类中可以使用不包含在任何方法中的静态代码块。当类被装载时,静态代码块被执行,且被执行一次。静态代码块经常被用来对类中定义的属性进行初始化。
5. Java中final修饰符都有什么作用?
以final修饰类属性,则该属性为常量;如果修饰方法,则方法称为最终方法,在子类当中不能被覆盖,利用这一点可以防止子类修改次方法,保证程序的安全性和正确性。
- 可用于修饰:成员变量,非抽象类(不能与abstract同时出现),非抽象的成员方法,以及方法参数;
2.final方法:不能被子类的方法重写,但可以被继承;
3.final类:表示该类不能被继承,没有子类;final类中的方法也无法被继承.
4.final变量:表示常量,只能赋值一次,赋值后不能被修改.final变量必须定义初始化;
5.final不能用于修饰构造方法;
6.final参数:只能使用该参数,不能修改该参数的值;
6. Java中float[10]arr,语句正确吗?
不正确,java中数组的声明就像是C++中的定义一个指针,可以初始化,但是不能指定长度。
_7. Java数组元素类型为基本数据类型和引用类型时,有什么不同?
引用数据类型 | 基本数据类型 |
---|---|
所有单元初值为null | 所有单元初值为0 |
创建时,在栈上存储其引用,对象的具体信息存储在堆 | 创建时,在栈上直接存储 |
成本最低的事情是学习,性价比最高的事情也是学习!