对象和对象引用的区别:
对象以类为模板产生,内存空间在堆中。在对象引用之前需要先进行声明,当声明被赋予对象之后才能称为对象引用,对象引用的内存空间在栈中。对象引用就好比对象的名片,也可以把对象和对象引用的关系比作电视机和遥控器的关系,对象引用就类似于C语言中的指针。
class Student{
String name;
int age;
}
public class RunStudent{
public static void main(String[] args){
Student A;//对象声明,内存空间在栈中
A = new Student;//给对象声明赋予对象,对象声明变为对象引用,对象的内存空间在堆中
//Student A = new Student;(声明后立即赋予对象)//
}
对象作为参数传递的特点:
对象是引用传递,当对象作为参数传递时,传递的是对象的地址。也就是说,对象只有一个。
class IntClass{
int value;
}
public class RunIntClass{
public static void modifyValue(IntClass s, int val){
s.value = val;//通过对象引用s进行对象赋值
}
public static void main(String[] args){
IntClass a = new IntClass();//产生一个IntClass对象,存放在在堆中,并被a所引用
modifyValue(a,8);//将a的地址传递给s,此时a和s所指的对象是同一个,赋值完毕后s所在的栈空间被释放,s和val消失
System.out.print(a.value);//a仍然引用该对象,通过a操作堆中的对象,显示其属性值
}
}
对象初始化顺序:
1.在没有继承的条件下,实例化一个对象,构造的先后顺序是:
静态成员变量>静态初始化块>成员变量>初始化块>构造方法
一般顺序为:先静态,后非静态;先变量,后初始化块,再是构造方法
public class Test{
public static void main(String[] args){
new A();
}
}
class A{
B m = new B("成员变量");
static B n = new B("静态成员变量");
{
System.out.println("初始化块");
}
static{
System.out.println("静态初始化块");
A(){
System.out.println("构造方法");
}
}
class B{
public B(String str){
System.out.println(str);
}
}
输出结果为:
静态成员变量
静态初始化块
成员变量
初始化块
构造方法
2.在有继承的条件下,,实例化一个对象,构造的先后顺序是:
父类静态成员变量>父类静态初始化块>子类静态成员变量>子类静态初始化块>父类成员变量>父类初始化块>父类构造方法>子类成员变量>子类初始化块>子类构造方法
一般顺序为:先父类,后子类;先静态,后非静态;先变量,后初始化块,再是构造方法
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
new Son();
}
}
class Parent{
B m = new B("父类成员变量");
static B n = new B("父类静态成员变量");
{
System.out.println("父类初始化块");
}
{
System.out.println("父类初始化块");
}
static {
System.out.println("父类静态初始化块");
}
public Parent() {
System.out.println("父类构造方法");
}
}
class Son extends Parent{
B m = new B("子类成员变量");
static B n = new B("子类静态成员变量");
{
System.out.println("子类初始化块");
}
{
System.out.println("子类初始化块");
}
static {
System.out.println("子类静态初始化块");
}
public Son() {
System.out.println("子类构造方法");
}
}
class B{
public B(String str){
System.out.println(str);
}
}
输出结果为:
父类静态成员变量
父类静态初始化块
子类静态成员变量
子类静态初始化块
父类成员变量
父类初始化块
父类构造方法
子类成员变量
子类初始化块
子类构造方法
类的static字段与非static字段的区别:
用static修饰符修饰的域变量不属于任何一个类的具体对象,而专属于类。其特点为它被保存在类的内存区(堆中)的公共存储单元中,而不是保存在某个对象的内存区中。因此任何一个对象访问它时,存取到的都是相同的数值。访问的方式为“类名.域名”,也可通过对象引用来访问。如用类的静态属性对产生的类对象个数进行统计。
class RunTest {
static int num = 0;
public RunTest(){
num++;
}
}
public class Test {
public static void main(String[] args){
RunTest m1 = new RunTest();
RunTest m2 = new RunTest();
System.out.println(m1.num);
System.out.println(m2.num);
System.out.println(RunTest.num);
}
}
输出结果为:
2
2
2
final修饰符的作用:
以final修饰类属性,则该属性为常量;如果修饰方法,则方法称为最终方法,在子类当中不能被覆盖。利用这一点可以防止子类修改此方法,保证了程序的安全性和正确性。
public Test{
final int num = 0;
final void Print(){
System.out.println("此方法不能被子类修改");
}
}
float[10] arr语句是否正确:
不正确。正确写法为float[] arr,数组是特殊的对象,该语句为声明浮点型数组对象的固定语句,表明arr是一个浮点型数组的声明,方括号里面不能加参数,声明一个浮点型数组并赋予对象的完整语句为:
float[] arr = new float[10];//产生一个具有10个单元,类型为float的数组对象
数组元素类型为基本数据类型和引用类型时的不同:
数组元素类型为基本数据类型时,数组中的元素为基本数据类型;数组元素类型为引用类型时,数组中的元素并不是实实在在的对象,而是对象引用。
MyClass[] a = new MyClass[10];//产生容纳10个MyClass的对象引用的数组,而不是产生10个MyClass对象
int[] b = new int[10];//产生容纳10个整型变量的数组