1. 静态方法与实例方法的区别
实例方法,对象的成员函数,必须实例化对象之后(new Object()),才能通过实例对象调用该对象的实例方法。
静态方法,使用static关键字声明,如main函数:
1
| public static void main(String[] args)
|
静态方法可以直接访问,而不需要实例化对象,访问形式为:类名.静态方法名。如:System.out.println(),其调用System包中的out类中的println()静态方法。
注意:类中的静态方法只能访问静态成员(即静态成员变量和静态方法),而不允许访问实例成员变量和实例方法。
2. 浅拷贝与深拷贝
拷贝,指将一个对象的内容复制到另一个对象。常利用拷贝构造函数,或原型模式完成该操作。
浅拷贝,是指在对象拷贝的过程中,只将对象A的成员变量的值复制到对象B的成员变量中。比如:
1 2 3 4 5 6 7 8 9 10 11 12 13
| class People { String name; int age;
People(String name, int age) { this.name = name; this.age = age; } People(People p) { this.name = p.name; this.age = p.age; } }
|
浅拷贝在成员变量都是值类型(String类不算一般引用类型)时,是完全没问题的。
但是,如果类中存在引用类型的成员变量,那这样浅拷贝是会出现问题的。如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| public class Demo { String name; People peo;
Demo(String name, People p) { this.name = name; this.peo = p; } Demo(Demo de) { this.name = de.name; this.peo = de.peo; } void printInfo() { System.out.println(name); peo.printPeopleInfo(); } }
class People { String name; int age;
People(String name, int age) { this.name = name; this.age = age; } People(People p) { this.name = p.name; this.age = p.age; } void printPeopleInfo() { System.out.println(name + " " + age); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public class Main { public static void main(String argv[]) { Demo A = new Demo("demo1", new People("Tom", 12)); A.printInfo();
Demo B = new Demo(A); B.name = "demo2"; B.peo.name = "ki"; B.peo.age = 20; B.printInfo();
A.printInfo(); } }
|
浅拷贝后,两个对象的引用类型成员变量指向同一个内存区域。因此,一个被修改后,另一个也会被影响。
为了避免这种bug的出现,就需要深拷贝了。如果熟悉C语言的话,其实这就是指针直接赋值的问题。
深拷贝,是为对象B(拷贝目的对象)的引用成员变量重新申请内存空间,并将对象A(拷贝源对象)的引用成员变量所指向的内容,深拷贝到对象B中引用成员变量所指向的新内存空间。
对上述示例的Demo类的拷贝构造函数做如下修改:
1 2 3 4
| Demo(Demo de) { this.name = de.name; this.peo = new People(de.peo); }
|
运行后,输出变成:
1 2 3 4 5 6
| demo1 Tom 12 demo2 ki 20 demo1 Tom 12
|
可以看到,改变B.pe对象中的值后并没有影响到A.pe对象中的值。
java中拷贝对象时,应根据适当场景使用对应拷贝方式。
3. 内部类