随着计算机革命的发展,“不安全”的编程方式已逐步成为编程代价高昂主要原因之一。
初始化和清理(cleanup)正是涉及安全的两个问题。
用构造器确保初始化
可以假想为编写的每个类都添加initialize方法。
该方法的名称提醒你在使用其对象之前,应该先调用initialize()。
然而,这同事意味着用户必须记得自己去调用此方法。
在Java中,通过提供构造器,类的设计者可确保每个对象都可以得到初始化。
创建对象时,如果其具有构造器,Java就会在用户有能力操作对象之前自动调用相应的构造器,从而保证初始化的进行。
构造器采用了与类相同的名字。
不接收任何参数的构造器叫做无参构造器或者默认构造器。
在Java中,“初始化”和“创建”捆绑在一起,两者不能分离。
方法重载
1、区分重载方法
每个重载方法都必须有一个独一无二的参数类型列表。甚至参数顺序不同都可以(不过一般,不要这么做,这样会使代码难以维护)。
2、涉及基本类型的重载
基类类型能从一个“较小”的类型自动提升至一个“较大”的类型,此过程一但涉及到重载,可能会照成一些混淆。
如果传入的数据类型(实际参数类型)小于方法中声明的形式参数类型,实际数据类型就会被提升。
char略有不同,如果无法找到恰好 接收char参数的方法,就会吧char直接提升至int。
如果实际传入的参数较大,就必须通过类型转换来执行窄化转换,否则,编译器会报错。
3、以返回值区分重载方法。
有时,你并不关心方法的返回值,所以行不通。
默认构造器
如果你写的类中没有构造器,则编译器就会帮你创建一个默认构造器。
但是,如果已经定义了一个构造器,编译器就不会帮你创建一个默认构造器。
this关键字
"所操作对象的引用"作为第一参数。
假设你希望在方法的内部得到当前对象的 引用。
由于这个引用由编译器“偷偷”的传入的,所以没用标示符可用。
但是,为此有个专门的关键字“this”。
this只能在方法内部引用,表示对“调用方法的那个对象”的引用。
如果在方法的内部调用同一个类的另外一个方法,就不必使用this,直接调用就可以(当然,也可以加)。
一般用法就是存在同名传入参数和域变量同名,通过使用this来指明是我自己的,不是传入的那个。
1、在构造器中调用构造器
package cn.partner4java.constructor.demo1;
/**
* 1、在构造器中调用构造器可以使用this(...)
* 2、被调用的构造器方法必须放在调用构造器的第一行
* 3、由于2,在一个构造器中只能调用本类的一个构造器
* @author partner4java
*
*/
public class Flower {
int petalCount = 0;
String s = "initial value";
public Flower(int petalCount) {
this.petalCount = petalCount;
System.out.println("Constructor int arg only,petalCount=" + petalCount);
}
public Flower(String s) {
System.out.println("Constructor String arg only,s=" + s);
this.s = s;
}
public Flower(int petalCount,String s) {
this(petalCount);
// this(s); //Can't call two;(Constructor call must be the first statement in a constructor)
this.s = s;
System.out.println("String & int s");
}
}
2、static的含义
static方法就是没有this的方法。
在static方法内部不能调用非静态方法,反过来可以。
在没有创建对象的前提下,仅仅通过类本身调用static方法。这实际上这是static方法的主要用途。
很像全局方法,Java中禁止使用全局方法。
清理:终结处理和垃圾回收
JVM:
http://blog.youkuaiyun.com/partner4java/article/details/7206650
http://blog.youkuaiyun.com/partner4java/article/details/7207741
终结方法:
http://blog.youkuaiyun.com/partner4java/article/details/7061188
成员初始化
局部变量不能不初始化。
package cn.partner4java.init.demo2;
public class Init {
private void f() {
int i;
i++;//Error,The local variable i may not have bean initialized
}
}
全局变量基本类型会默认初始化。
1、指定初始化
需要注意的是指定初始化和初始化顺序。
构造器初始化
无法阻止自动初始化的进行,他将在构造器被调用之前发生。
1、初始化顺序
在类的内部,变量定义的先后顺序决定了初始化的顺序。
即使变量定义散步在方法定制之间,他们仍旧会在任何方法(包括构造器)被调用之前得到初始化。
2、静态数据的初始化
无论创建多少个对象,静态数据都只占一份存储区域。
static关键字不能应用于局部变量,因为他只能作用于域。
如果一个域是静态基本类型域,且也没有对他进行初始化,那么他就会获得基本类型的标准初值;如果他是对象引用,那么他的默认初始化值就是null。
静态存储区域是何时初始化的?
package cn.partner4java.init.demo3;
public class Bowl {
public Bowl(int marker) {
System.out.println("Bowl(" + marker + ")");
}
void f1(int marker){
System.out.println("f1("+ marker +")");
}
}
package cn.partner4java.init.demo3;
public class Table {
static Bowl bowl1 = new Bowl(1);
public Table() {
System.out.println("Table()");
bowl2.f1(1);
}
void f2(int marker){
System.out.println("f2("+ marker +")");
}
static Bowl bowl2 = new Bowl(2);
}
package cn.partner4java.init.demo3;
public class Cupboard {
Bowl bowl3 = new Bowl(3);
static Bowl bowl4 = new Bowl(4);
public Cupboard() {
System.out.println("Cupboard()");
bowl4.f1(2);
}
void f3(int marker){
System.out.println("f3("+ marker +")");
}
static Bowl bowl5 = new Bowl(5);
}
package cn.partner4java.init.demo3;
/**
* 总结一下创建过程,假设有个名为Dog的类:
* 1、即使没有显式的使用static关键字,构造器实际上也是静态方法。
* 因此,当收次创建类为Dog的对象时(构造器可以看做静态方法),
* 或者Dog的静态方法/静态域首次被访问时,Java解释器必须查找类路径,以定位Dog.class文件。<br/>
* 2、然后载入Dog.class,有关静态初始化的所有动作都会执行。
* 因此,静态初始化只在Class对象首次加载的时候进行一次。<b/>
* 3、当用new Dog()创建对象的时候,首先将在堆上为Dog分配足够的存储空间。<br/>
* 4、这块存储空间会被清零,这就自动的将Dog的所有基本数据类型设置从了默认值,而引用设置成了null。<br/>
* 5、执行所有出现于字段定义出的初始化动作。<br/>
* 6、执行构造器。
* @author partner4java
*
*/
public class StaticInitialization {
public static void main(String[] args) {
System.out.println("Creating new Cupboard in main");
new Cupboard();
System.out.println("Creating new Cupboard in main");
new Cupboard();
table.f2(1);
cupboard.f3(1);
}
static Table table = new Table();
static Cupboard cupboard = new Cupboard();
}
//后台打印:
//Bowl(1)
//Bowl(2)
//Table()
//f1(1)
//Bowl(4)
//Bowl(5)
//Bowl(3)
//Cupboard()
//f1(2)
//Creating new Cupboard in main
//Bowl(3)
//Cupboard()
//f1(2)
//Creating new Cupboard in main
//Bowl(3)
//Cupboard()
//f1(2)
//f2(1)
//f3(1)
3、显式的静态初始化
Class Cups {
static Cup cup1;
static Cup cup2;
static{
cup1 = new Cup(1);
cup2 = new Cup(2);
}
}
4、非静态实例初始化
package cn.partner4java.init.demo4;
public class Mug {
public Mug(int marker) {
System.out.println("Mug("+ marker +")");
}
void f(int marker){
System.out.println("f("+ marker +")");
}
}
package cn.partner4java.init.demo4;
/**
* 实例初始化子句在构造器之前执行
* @author partner4java
*
*/
public class Mugs {
Mug mug1;
Mug mug2;
{
mug1 = new Mug(1);
mug2 = new Mug(2);
System.out.println("mug1&mug2 initialized");
}
public Mugs() {
System.out.println("Mugs()");
}
public Mugs(int i){
System.out.println("Mugs(int)");
}
public static void main(String[] args) {
System.out.println("Inside main()");
new Mugs();
System.out.println("new Mugs() completed");
new Mugs(1);
System.out.println("new Mugs(1) completed");
}
}
//后台打印:
//Inside main()
//Mug(1)
//Mug(2)
//mug1&mug2 initialized
//Mugs()
//new Mugs() completed
//Mug(1)
//Mug(2)
//mug1&mug2 initialized
//Mugs(int)
//new Mugs(1) completed