一,对象与对象引用的区别是什么? 请举例说明
为了接下来的分析,先建立一个Demo类
public class Demo{
public Demo{
}
}
常用的创建对象:Demo demo=new Demo();
这一条语句,其实包括了四个动作: 1)右边的“new Demo”,是以Demo类为模板,在堆空间里创建一个Demo对象。 2)末尾的()意味着,在对象创建后,立即调用Demo类的构造函数,对刚生成的对象进行初始化。 3)左边的“Demo demo”创建了一个Demo类引用变量,它存放在栈空间中。也就是用来指向Demo对象的对象引用。 4)“=”操作符使对象引用指向刚创建的那个Demo对象。
等价于
Demo demo;//创建对象引用 作为局部变量分配在栈stack上
demo=/*将对象引用指向对象*/new Demo();//创建对象 对象分配在堆heap上
区别: (1)一个对象引用可以指向一个对象,也可以不指向对象
Demo demo;
demo=new Demo();
Demo demo;
(2)一个对象可以被一个对象引用引用,也可以被多个对象引用同时引用
Demo demo;
demo=new Demo();
Demo demo1,demo2,demo3;
demo1=new Demo();
demo2=demo1;
demo3=demo2;
二,对象作为参数传递的特点是什么?请举例说明
特点: 基本数据类型作为参数传递是值传递,而对象是引用传递,传递的是对象的地址,对象只有一个。
例如: 将实参对象引用a中的对象的地址复制到形参对象引用s中,s和a指向同一个对象。
class IntClass {
int value;
}
public class RunIntClass {
public static void modifyValue(IntClass s, int val){
s.value = val;
}
public static void main(String[] args) {
IntClass a = new IntClass();
modifyValue(a,8);
System.out.println(a.value);
}
}
三,对象初始化顺序是怎样的?请举例说明
java类初始化顺序是:
(1)初始化类变量(即static修饰的成员变量),并未赋值。不管写的位置在哪里,只要是类变量,系统总会先找到它进行变量初始化。 (2)执行静态代码块和类变量定义式,两者根据写的位置来决定先后,先写先执行。 (3)初始化实例变量(即未被static修饰的成员变量),并未赋值。同样的,不管写的位置在哪里,在创建对象时执行到这步时,系统总会找到它进行变量初始化。 (4)执行构造代码块和实例变量定义赋值式,两者同样根据写的位置先后来决定执行顺序先后。 (5)执行构造函数。构造函数同样可以调用静态变量和实例变量。
关于这个初始化顺序,其实一句话可以概括: 先初始化类变量然后赋值,再初始化实例变量然后赋值。 例如:
package hello;
class IntClass{
int value;
public IntClass() {}
public IntClass(int val) {
value=val;
}
}
public class IntClassConstructor {
public static IntClass getInstance() {
IntClass s=new IntClass(8);
return s;
}
public static void main(String[] args) {
IntClass a=new IntClass();
System.out.println(a.value);
a=getInstance();
System.out.println(a.value);
}
}
四,类的static字段与非static字段的区别是什么?什么场景应该使用static修饰符?请举例说明
1.static字段: (1).修饰数据成员:用static修饰符修饰的数据成员是不属于任何一个类的具体对象,而是属于类的静态数据成员; 访问方式为通过类名加点操作符来访问,也可通过对象引用来访问。 《Java开发手册》强制使用类名(而不是该类的对象引用)访问静态方法和静态变量。
例如: static数据成员初始化:
class IntClass{
static int num=0;
int value=5;
public IntClass() {}
public IntClass(int val) {
value=val;
}
}
(2).static类方法:但可以被所有对象所访问,引用这个方法时,可以使用对象名做前缀,也可以使用类名做前缀。 《Java开发手册》强制使用类名(而不是该类的对象引用)访问静态方法和静态变量; static方法内部的代码,只能访问类中的static属性或方法,不能直接访问类中的非static属性或方法(因为那是对象方法),但非static方法(对象方法)可以访问static数据成员; main方法是特殊的静态方法,是application程序入口点,必须写成public static void main(String [] args)的形式。
例如: static方法:
static int countNum() {
return num;
}
(3).静态代码块:一个类中可以使用不包含在任何方法体中的静态代码块,当类被装载时,静态代码块被执行,且只被执行一次,静态代码块经常用来对类中定义的属性进行初始化。 例如:
public class Test2 {
static int value ;
static {
value = 3;
System.out.println("value="+value);
}
public static void main(String[] args){ }
}
2.非static字段: (1).数据成员:被复制到对象中,每个对象中都有其各自的属性,通过对象引用访问。 (2).方法:通过对象引用调用,在调用时系统会为方法开辟一个栈空间,用于存放方法中的局部变量和形式参数,并且方法在执行时还能访问复制到对象中的属性,其效果如同方法也被复制的对象中一样。 方法执行完毕之后,栈空间被释放。
3.什么时候使用static修饰符: 如类里对象公有的属性,比如类中所有对象的个数等等,就可定义为静态属性为类所共享。
五,Java中final修饰符都有什么作用?请举例说明
1.final修饰属性,则属性为常量。 例如:
final int NUM = 20;
NUM = 30;
2.如果修饰方法,则该方法在子类当中不能被覆盖,可防止任何继承类修改此方法,保证了程序的安全性和正确性。 例如:
class Parent {
public final void method1(){}
}
class Child extends Parent {
public final void method1(){…}
3.final修饰类,则该类不能被继承。 例如:
class Parent {
}
final class Person extends Parent{
}
class Child extends Person{
}
六,Java中float[10] arr; 语句正确么?为什么?
不正确。 Java语言数组声明时,不可在方括号内指定数组大小。因为此时并未分配数组空间,可以使用new给数组分配空间,指定数组长度。 例如:
int[] arr = new int[10];
七,Java数组元素类型为基本类型和引用类型时,有什么不同?请举例说明
1.数组元素为基本数据类型 例如:
int[] arr = new int[10];
产生一个有10个单元,类型为int的数组对象,所有单元的初值为0。
2.数组元素为引用类型 例如:
String[] example = new String[10];
for(String x: example)
System.out.println(x); 输出结果为10个null
产生一个具有10个单元的数组对象,每个单元存放的是1个String对象的引用,所有单元的初值为null,此时并未创建具体的String对象。
example[0] = new String(“ab”);
为数组对象引用赋值后,才能使用数组元素,否则会抛出 NullPointerException异常。
|