目录
1、方法重载
2、默认构造器
3、this关键字
4、static关键字
5、初始化
1、方法重载
java中方法重载的意思是在同一个类中可以存在方法名相同的方法,而方法的参数类型不同,即使两个方法的参数列表完全相同但只要顺序不同也可以,方法的重载适应于构造器,与方法的返回值类型无关。而java就是根据参数列表来区分具体调用哪一个方法。
1 public class Tree { 2 int height; 3 //构造器的重载 4 Tree(){ 5 System.out.println("hello"); 6 } 7 8 Tree(int inithHight){ 9 height = inithHight;10 System.out.println("hello " + height);11 }12 13 //普通方法的重载14 void info(String s, int i){15 System.out.println("method 1");16 }17 18 void info(int i, String s){19 System.out.println("method 2");20 }21 22 public static void main(String[] args) {23 new Tree().info(1, "123");24 new Tree().info("123", 1);25 new Tree(4).info(1, "1234");26 }27 }
1 public class Test2 { 2 void f1(double d){ 3 System.out.println("f1(double)"); 4 } 5 6 void f2(int i){ 7 System.out.println("f2(int)"); 8 } 9 public static void main(String[] args) {10 //输出f2(int)11 new Test2().f1(1);12 //报错找不到该方法13 //new Test2().f2(1.0);14 }15 }
2、默认构造器
当我们定义的类中没有定义任何构造器时,编译器会提供给我们一个默认的无参构造器,但是只要我们,注意前提,当我们没有定义任何构造器时。 所以当我们定义了自己的构造器时而其中又没有无参构造器,再去new这个对象(new Dog() )就会报错,找不到构造器。
3、this关键字
this代表类的当前对象,就是指向当前对象的引用,当我们在方法内部调用同一个方法是,可以不必使用this,其实这就是我们平常习惯性的写法,编译器会自动帮我们添加,试想要是我们都加上this不就让代码的可读性降低了吗?
this用得最多的地方就是在构造器中,像下面这样的代码你肯定经常看到
因为为了代码的可读性,通常我们对标识符命有意义的词,所以当成员变量名和方法的局部变量名相同时,为了区分就在成员变量前加上this来与局部变量区分。
1 class Test3(){2 int age;3 Test3(int age){4 this.age = age;5 }6 }
用this调用构造器,因为用this调用的构造器只能放在构造器第一行,所以一个构造器内只能有一个用this调用的构造器。讲得有点不清楚,构造器内调用其他构造器只能用this,这样应该清楚点了,神马还有其他办法调吗?请告诉我!像方法内调用同一个类中的其他方法一样调用吗?不行额,编译器会把这种写法当成调用普通方法。
1 public class Test2 { 2 int age; 3 String s; 4 5 Test2(int age){ 6 this.age = age; 7 } 8 9 Test2(int age, String s){10 //只能放在第一行11 this(22);12 this.s = s;13 }14 }
4、static关键字
static可以用来修饰成员变量、方法,修饰的变量特点就是所有该类的对象共享该变量,而用来修饰方法其实就是表示没有this的方法,别人可是在加载类的class文件时就执行了的,那时候可还没有对象哦,而且只在首次加载Class对象时执行一次。具体对象的创建过程在第5点讲。在static方法内部不能直接调用非静态方法,因为非静态方法必须由对象来调用啊,你肯定现在有对象没有?当然不能确定。反过来非静态方法可以调用静态方法哦。当在没有创建任何对象的前提下,静态方法仅能通过类本身来调用,写法是类名.方法名,看见没,别人调用方式都透露了这么多信息,这可是static方法的常见用途,你去看看工具类,我要用你的方法,还要每次创建对象,多麻烦。还有用在单例中,当我只想提供一个对象时,我会私有化构造器,用一个私有的常量来接受对象,这就可以保证只有一个对象了,当然这只是简单的说说,那别人怎么创建这个类的对象呢,那我给你提供个公共的static方法你不就可以通过类名调这个方法就ok了嘛,对象到手。
5、初始化
在说构造器初始化前先说说成员(也就是类的字段)的初始化,为保证变量在使用前都得到了恰当的初始化java编译器会对我们未赋值的变量给提供默认值,注意方法内的局部变量你不赋值可是会报错的,别人才不会管你那么多。
在有构造器初始化的同事有其他初始化方式,比如说静态代码块初始化,非静态代码块初始化,这些初始化是可以都会执行的。而且会在构造器调用之前发生。
那么就再来讲讲初始化的顺序,先看下面这个例子吧!注意:静态代码块和只有一句的静态实例初始化动作没区别,你要找区别就是把他们弄到了一起然后加了个括号就成了静态代码块了,非静态代码块同理。
1 class M1{ 2 M1(int i){ 3 System.out.println("M1(" + i + ")"); 4 } 5 } 6 7 class M2{ 8 static{ 9 System.out.println("static 1");10 }11 //new M1(1);12 M1 m1 = new M1(1);13 static{14 System.out.println("static 2");15 }16 17 M2(){18 System.out.println("M2()");19 m3 = new M1(33);20 }21 22 M1 m2 = new M1(2);23 void f(){24 System.out.println("f()");25 }26 M1 m3 = new M1(3);27 }28 29 public class Test2 {30 public static void main(String[] args) {31 M2 m = new M2();32 m.f();33 System.out.println("--------分隔线-------");34 M2 m2 = new M2();35 }36 37 }38 /*39 static 140 static 241 M1(1)42 M1(2)43 M1(3)44 M2()45 M1(33)46 f()47 --------分隔线-------48 M1(1)49 M1(2)50 M1(3)51 M2()52 M1(33)53 */
由运行结果可以观察到重复创建对象静态代码块只执行了一次,而且是在创建对象或者调用类的方法时才会执行一次,这个也是最先执行的,然后就是非静态实例的初始化了,这个每创建一次对象都会执行一次,然后就是构造器的执行了,其实可以简单的理解因为静态的成员是类公用的嘛,第一次初始化了不就保证了成员不是null嘛,后面就用不着了,但非静态实例初始化和构造器初始化都是每个对象单独的一份,当然每次用都要初始化咯。
总结一下对象的创建过程,假设有个Dog类:
1、当一次创建Dog类的对象或者调用Dog类的静态方法时,java编译器就会查看类路径,查找Dog.Class文件。
2、然后加载Dog.Class,有关静态初始化的过程就在这个时候执行,而且只执行一次,注意:所有的都会执行。
3、当用new Dog()创建对象的,就在堆上给该对象分配的存储空间。
4、然后会对该类的变量进行初始化,全部初始化成默认值,引用设为null。
5、非静态代码块的初始化操作,这时候会把相应的默认值替换掉。
6、执行构造器进行初始化,这不非静态实例、静态实例初始化的值又可能被替换掉嘛。
原文参考自Thingk in java,转载请注明原文出处: