初始化和清理,正式设计安全的两个问题。
什么是构造器(构造函数)
1.构造器,也称之为构造函数。不接受任何参数的构造器叫做默认构造器,java文档中通常使用术语 无参构造器。
2.构造器有助于减少错误,并使代码更易于阅读。
3.在Java中,“初始化”和“创建”捆绑在一起,两个不能分离。
4.构造器是一种特殊的方法,没有返回值。
方法重载(Overload)
重载顾名思义,重新加载。当一个方法因为参数的的原因,使得所需要扩展的功能无法实现。此时就需要方法重载。
重载只看方法签名,方法签名指的是方法名称和方法的参数列表。当方法名称相同,参数列表不同时,才能叫做重载方法。不需要看返回值类型,因为通过看返回值类型不能够辨别出需要调用的方法。
如何区分方法重载呢?规则很简单,每个重载的方法都必须有一个独一无二的参数类型列表。
在重载中,参数顺序的不同,也足以区分两个方法。不过,一般情况下不要这么做,这回事的代码难以维护
public class OverloadOrder{
static void f(String s,int i){
System.out.println("String:"+s+", int:"+i);
}
//overload
static void f(int i,String s){
System.out.println("String:"+s+", int:"+i);
}
public static void main(String[] args) {
f("String first",11 );
f(99,"Int first");
}
}
输出结果
String:String first,int:11
int:99,String:Int first
如何调用重载方法呢?
通过判断传入的数据类型,在配合方法的参数列表,就可以判断所用的是哪个重载方法。
如果传入的数据类型小于方法中声明的形式参数类型,实际参数类型就会被提升。char类型略有不同,如果无法找到恰好接收char参数的方法,就会把char直接提升至int型。
如果传入的实际参数较大,那么就会将传入的类型缩小,可能会造成数据的丢失。
默认构造器
默认构造器(无参构造器)是没有行使参数的,它的作用就是创建一个“默认对象”。
当一个类中没有显示的创建任何的构造器的时候,虚拟机就自动的创建一个隐式的默认构造器,保证对象能够顺利的被创建。
this关键字
在有些情况,当你想要在方法的内部使用当前类的引用,那么不需要创建本类对象再通过对象引用,可以直接使用this关键字。表示对“调用方法的那个对象”的引用。
但如果在方法内部调用同一个类的另一个方法,就不必使用this,直接调用就行。
但是this关键字也不是何时何地都需要用到的,只有在必要的时候使用,否则就会造成代码的阅读性很差。
this关键字也可以存在构造函数中,调用当前类的其他的构造函数(重载的)。以this()的形式存在构造函数的第一行。
super和this关键字都是处在构造函数的第一行,且只能存在一个。
static关键字
static方法就是没有this的方法。static方法随着类的加载而加载,而类中的其他方法随着对象的加载而创建,static方法不能够调用非静态方法,反过来确可以(与两种方法的加载方式有关)。
为什么要用static(静态)关键字?
假如在一个班级里的每一个同学就是一个对象,并且各个同学都是自己的属性(特征等)和行为(方法)。假设,每个同学都有一个饮水机,那么当同学需要喝水的时候调用自己在饮水机取水的功能就可以,这样是可以满足的。但是毕竟一个班的空间有限,不可能给每个同学一个饮水机。
这时,就可以将饮水机设置为static(静态的),不随这对象的加载,而是随着类的加载而加载,这样不但每个同学都能喝水,也节省了教室的空间。
所以用static关键字可以节省空间,优化代码。
成员的初始化
Java尽力保证:所有变量在使用前都能够得到恰当的初始化。对于方法的局部变量,Java以编译时错误的形式来贯彻这种保证。
1.构造器初始化
public class Counter {
int i;
Counter() {
i = 7;
}
}
通过这种方法,构造器(构造函数)将会将i初始化为7,但是此时,成员变量i已经被初始化了两次,第一次被默认初始化为0,第二次构造器将其初始化为7。对于所有基本类型和对象引用,包括在定义时已经指定初值的变量,这种情况都是成立的。
1.1初始化的顺序
看下面的代码
class House{
Window w1 = new Window(1);//在构造器的前面定义
House() {
System.out.println("House()");
w3 = new Window(33);
}
void f(){
System.out.println("f()");
}
Window w2 = new Window(2);//在构造器的后面定义
Window w3 = new Window(3);
}
public class OrderOfInitialzation{
public static void main(String[] args) {
House h = new House();
h.f();
}
}
输出结果为:window(1)
window(2)
window(3)
House()
Window(33)
f()
尽管 Window的几个对象分布的类各处,但是确是能够保证它们全部都会在调用构造器或其他方法之前得到初始化。
从上面可以总结出初始化的顺序为:
1.字段默认(隐式)初始化
2.字段显式初始化
3.构造器的初始化
但是如果存在静态变量的话,静态的变量首先初始化,且随着类的加载而加载,这三部分。