一 、java中的构造方法是可以重载的
java 构造方法的重载与参数类型无关,只与参数个数有关,为什么与类型无关是因为类型在类中已经定义过了。
构造方法的重载只是给不同的类型参数赋值而已。
但是重载方法会产生如下的一个问题:
此时我们使用string name进行构造,那么又因为编译器的就近匹配原则而导致无法成功构造。
此处的name = name 实质为66 = 66,并未给成员变量name赋值。
所以此时引入this关键字:
1 this修饰成员变量:使用 this.属性名称 打破就近匹配原则,直接从类中使用变量。
2 this 修饰方法
2.1 this 修饰成员方法,表示调用类中的成员方法 使用 this.方法名称 。
即使此处不加this.编译器也会加上
此处为class文件
IDEA快捷生成构造方法:
2.2 this调用构造方法
this(参数) //调用构造方法
特别的,成员方法中无法调用构造方法,原因是成员方法已经产生对象执行操作了,而构造方法是用来产生对象为对象赋初始值的,就像你买个面包(创立新对象),撒上奶油(赋初始值),吃了(执行成员方法),然后你调用构造方法怎么把这个吃掉的面包(对象)重新撒上奶油(赋初始值)?所以这不可能。如果这么写的话会报错:
但是构造方法之间可以相互调用,因为构造方法只是在产生对象时赋初始值而已,不同的构造方法相互调用就是产生不同的对象并为其赋初始值而已,就像你同时买了面包和薯条(不同的构造方法需要产生的对象),给面包涂上奶油(赋初始值),给薯条撒上番茄酱(赋初始值),然后吃掉(执行成员方法)。特别的,如果构造方法2中需要执行构造方法1(比如起床这个构造方法2需要执行闹钟响构造方法1),那么可以用this在构造方法2中调用构造方法1即可。不需要把闹钟响再重新写一遍。
关于在构造方法之间用this调用构造方法的几个注意点:
A.this构造方法调用必须在构造方法首行进行(很好理解,代码顺序进行,如果构造方法1闹钟响不执行,那么构造方法2起床也执行不了)
B 一个构造方法只能调用一个构造方法,因为这种调用是具有先后顺序的,如果调用两个就会造成错误
C 构造方法调用不能成环,比如构造方法1闹钟响,构造方法2起床(包括构造方法1,在此调用),构造方法3吃早饭(包括构造方法2,在此调用),不存在此时构造方法1还包括构造方法3的情况,也就是此时构造方法1是不可以调用构造方法3的。
3 this表示当前对象的引用
当前this通过哪个对象来调用成员方法或成员属性,那么这个this就指代那个对象。
举个例子
我们创建一个类,然后在后面新建了两个该类中的对象,一个叫per1一个叫per2,那么假设我们使用per1来调用成员方法与属性,在调用时,无论是方法还是属性语句里的this都指代该per1对象。
static 关键字
static关键字与对象无关,static表示静态,和类有关,和具体的对象无关。
1 static修饰属性,为类属性,静态属性,放在JVM的方法区
在类中定义类属性 加static关键字,举个例子:中国人是一个类,性别,年龄,身高等属性与具体对象强相关,因此是成员属性不需要加static,而每个中国人国籍都是中国,那么国籍就是中国人这个类的类属性,只要是中国人,都具备这个属性,那么加上static ,放在JVM方法区,不放在堆中。正因为如此,当类中随便哪个对象对类属性进行改变的时候,那么该类中其他人的类属性也一同改变。
tips:java中不支持在任何方法中定义静态变量。方法中定义的变量一定都是局部变量,在栈帧中存储。比如在main方法中定义static属性是不可行的。
特别的,如果创建的类中的一个新的对象的对象值为null,哪怕该对象不指代类中的任何对象,也仍然可以调用类属性/类方法。因为类属性与对象无关,但此时调用成员属性和成员方法就会报错,因为没有指代的对象,无法操作。
2 static修饰方法,为类方法,直接通过类名称调用,与对象无关。
类名称.方法名称(参数)例如:Chinese.test();
一个类的工具方法一般设为类方法,与具体对象无关。例如
3 static修饰的静态域(静态方法与静态属性)和成员域(成员属性和成员方法)之间的关系
A能否在静态方法中调用成员方法或成员变量?
不行,因为静态方法是没有对象的,但是成员方法和成员变量必须存在对象才能调用,矛盾。
(静态方法:中国人(类)爱中国(方法),成员方法:张三(具体对象)偷苹果(成员方法),显然在类方法中调用成员方法时不存在张三这个具体对象,因此不可能执行成功)
B能否在成员方法中调用静态方法?
可以,因为成员方法调用时已经存在具体对象了,那么该对象所对应的类,类中的类方法和类属性当然可以调用。(还是上面的例子,此时已经存在了张三(对象),执行张三偷苹果(成员方法),再调用类方法(中国人爱中国),可以,不冲突)
特别的,static无法修饰外部类(因为类的设计是用来产生对象的,新的对象必然不同。你用static修饰,把它静态了,都一样了,还怎么产生对象?),但可以修饰内部类。
4 static变量的初始化
就地初始化
或在静态代码块中初始化。到此,如下介绍四种代码块。
代码块:使用{}定义的一段代码就叫代码块,有四种。
四种代码块:
1 普通代码块:直接定义在方法内部,不加任何修饰符定义的代码块。
普通代码块的内容只在其生命周期内有效,就是{}内。
此处方法重名,特别的,如果想给int a 赋值 30,下面应该写成 a = 30.而不是int a
2 构造块:直接定义在类中,使用{}框起来的代码块。
特别的,构造块优先于构造方法执行
下图为编译后的class文件,我们可以看到构造块在构造方法之前
3 静态代码块:一般用于初始化静态变量,在类加载时使用一次,与具体对象无关,若有多个静态块,则按顺序执行。
上图中我们可以看到,一个类在执行时,最先执行静态块生成静态变量,然后使用构造块构造对象,最后使用构造方法根据构造块内容创建出具体对象。
特别的,主类中的静态块会优先于主方法执行。原理与上面其他类是一样的。
4 同步代码块:使用synchronized(){}包裹起来的代码块,此处未学习。