冰凍三尺非一日之寒,滴水石穿非一日之功
打好基礎(chǔ)是關(guān)鍵,筆者準(zhǔn)備老老實(shí)實(shí)搞搞基礎(chǔ)了,不僅為了7月份的實(shí)習(xí)面試,還是為了自我能力的提升,基礎(chǔ)的重要性不可忽視。
牢騷發(fā)完了,進(jìn)入正題吧。
1.用構(gòu)造器進(jìn)行初始化
- 構(gòu)造器采用與類相同的名稱,因此“每個(gè)方法首字母小寫”的編碼風(fēng)格不適合用在構(gòu)造器中
- 構(gòu)造器是一種特殊類型的方法,因?yàn)樗鼪]有返回值。這與返回值為空(Void)不同。
- 默認(rèn)構(gòu)造器是沒有形式參數(shù)的,他的作用是創(chuàng)建一個(gè)默認(rèn)對(duì)象。如果類中沒有構(gòu)造器,那么編譯器會(huì)自動(dòng)幫你創(chuàng)建一個(gè)默認(rèn)構(gòu)造器。
- 但是,如果你在類中已經(jīng)定義了一個(gè)構(gòu)造器(無論是否有參數(shù)),那么編譯器就不會(huì)幫你自動(dòng)創(chuàng)建默認(rèn)構(gòu)造器了。
2.方法重載
為了讓方法名相同而讓形式參數(shù)不同(獨(dú)一無二的參數(shù)類型)的構(gòu)造器同時(shí)存在,必須用到方法重載。要對(duì)明顯相同的概念使用了不同的名字,就會(huì)令人困惑,好在有了方法重載,可以為二者使用了相同的名字。
class NBA{
public NBA() {
System.out.println("這是無參構(gòu)造");
}
public NBA(String team) {
System.out.println("這是有一個(gè)參數(shù)的構(gòu)造"+team);
}
}
public class Demo1 {
public static void main(String[] args) {
new NBA();
new NBA("火箭");
}
}
2.1基本類型的重載
如果傳入的數(shù)據(jù)類型(實(shí)參)小于方法中聲明的形參類型,那么數(shù)據(jù)類型就會(huì)被提升。反之,需要將實(shí)參進(jìn)行窄化。
2.2不能以返回值區(qū)分方法重載
有時(shí)候,我們并不關(guān)心方法的返回值,
int i(){
return 0;
}
float i(){
return '0';
}
編譯不過去。當(dāng)調(diào)用i()時(shí),Java并不知道該調(diào)用哪個(gè)
this關(guān)鍵字
this關(guān)鍵字<font color=#f00 size=4 face="黑體">只能在方法內(nèi)部使用</font>,表示對(duì)<font color=#f00 size=4 face="黑體">“調(diào)用方法的那個(gè)對(duì)象”</font>的引用。如果在方法內(nèi)部調(diào)用同一個(gè)類中的另一個(gè)方法時(shí),就不必用this,直接調(diào)用即可
只有當(dāng)需要明確指出對(duì)當(dāng)前對(duì)象的引用時(shí),才需要使用this關(guān)鍵字。
class NBA {
int i;
public NBA increment() {
i++;
return this;
}
public void print() {
System.out.println(i);
}
}
public class Demo1 {
public static void main(String[] args) {
new NBA().increment().increment().print();
}
}
在構(gòu)造器中調(diào)用構(gòu)造器
class NBA {
int i;
NBA(String team){
System.out.println(team);
}
NBA(int year){
System.out.println(year);
}
NBA(String team,int year){
this(team); //只能在構(gòu)造器的第一行調(diào)用其它構(gòu)造器
// this(year); //在構(gòu)造器中調(diào)用1個(gè)的構(gòu)造器
}
public void print() {
// this();//在非構(gòu)造器中不能調(diào)用構(gòu)造器
System.out.println(i);
}
}
public class Demo1 {
public static void main(String[] args) {
new NBA("火箭", 20);
}
}
- <font color=#f00 size=4 face="黑體">盡管this可以調(diào)用一個(gè)構(gòu)造器,但卻不能調(diào)用二個(gè)</font>
- <font color=#f00 size=4 face="黑體">構(gòu)造器必須置于最始處</font>
- <font color=#f00 size=4 face="黑體">除構(gòu)造器之外,編譯器禁止在其他任何方法中調(diào)用構(gòu)造器。</font>
static含義
static方法就是沒有this的方法,在static方法的內(nèi)部不能調(diào)用非靜態(tài)方法(類加載器將會(huì)去加載類,而static修飾的方法是屬于類的,因此,static方法同時(shí)也被加載,而非靜態(tài)方法需要對(duì)象,此時(shí)還沒有生成對(duì)象,所以static方法的內(nèi)部不能調(diào)用非靜態(tài)方法),反之,可行。在沒有創(chuàng)建對(duì)象的前提下,僅僅通過類本身來調(diào)用static方法,這正是static主要用途。static方法可以訪問其他static域和方法。
面向?qū)ο蟮乃枷胧恰跋驅(qū)ο蟀l(fā)送消息”,而由于static方法就是沒有this的方法,所以并不是面向?qū)ο笏枷?,因此,盡量少用static.
清理:終結(jié)處理和垃圾回收
- 在Java中,對(duì)象并非總是被垃圾回收
- 垃圾回收只與內(nèi)存有關(guān)
- 如果jvm并未面臨內(nèi)存耗盡的情形,它就不會(huì)去執(zhí)行垃圾回收以恢復(fù)內(nèi)存的。
關(guān)于垃圾回收機(jī)制建議看《深入理解Java虛擬機(jī)》,這本書是我的下月計(jì)劃。
成員初始化
java盡力保證:所有變量在使用前都能得到恰到的初始化。
而類的數(shù)據(jù)成員,即字段,都會(huì)有一個(gè)初始值。
class A{}
class NBA {
int i;
float f;
boolean b;
char c;
byte by;
short s;
long l;
double d;
A a;
void print(){
System.out.println(i); // 0
System.out.println(f); // 0.0
System.out.println(b); //false
System.out.println(c); //
System.out.println(by); // 0
System.out.println(s); // 0
System.out.println(l); // 0
System.out.println(d); // 0.0
System.out.println(a); // null
}
}
public class Demo1 {
public static void main(String[] args) {
new NBA().print();
}
}
初始化順序
在類的內(nèi)部,變量定義的先后順序決定了初始化的順序。即使變量定義散布于方法定義(包括構(gòu)造器)之間,它們也會(huì)在任何方法被調(diào)用之前得到初始化。
class CBA{
CBA(String team){
System.out.println(team);
}
}
class NBA {
CBA cba = new CBA("上海嗶哩嗶哩"); //在構(gòu)造器方法前
NBA(){
System.out.println("NBA構(gòu)造器");
}
CBA cba2 = new CBA("浙江稠州銀行"); //在構(gòu)造器方法后
void f(){
System.out.println("普通方法");
}
CBA cba3 = new CBA("北京首鋼");//在普通方法后
}
public class Demo1 {
public static void main(String[] args) {
new NBA().f();
}
}
輸出:
上海嗶哩嗶哩
浙江稠州銀行
北京首鋼
NBA構(gòu)造器
普通方法
靜態(tài)數(shù)據(jù)的初始化
無論創(chuàng)建多少個(gè)對(duì)象,靜態(tài)數(shù)據(jù)都只占用一份存儲(chǔ)區(qū)域。static關(guān)鍵字不能應(yīng)用于局部變量,因此它只能作用于域。
class WCBA{
WCBA(){
System.out.println("WCBA構(gòu)造器");
}
}
class CBA{
static WCBA wcba= new WCBA();
CBA(String team){
System.out.println(team);
}
}
class NBA {
NBA(){
System.out.println("NBA構(gòu)造器");
}
}
public class Demo1 {
public static void main(String[] args) {
new CBA("浙江");
new NBA();
}
static CBA cba3=new CBA("上海");
}
結(jié)果:
WCBA構(gòu)造器
上海
浙江
NBA構(gòu)造器
初始化的順序是先靜態(tài)對(duì)象(如果他們尚未因前面的對(duì)象創(chuàng)建過程而被初始化),然后是非靜態(tài)對(duì)象。
在main()方法執(zhí)行之前,先執(zhí)行靜態(tài)對(duì)象,也就是cba3,需要加載CBA類,同理,CBA類取加載WCBA,執(zhí)行WCBA的構(gòu)造,再執(zhí)行CBA構(gòu)造,最后執(zhí)行main方法,值得注意的是,new CBA("浙江"),直接輸出浙江二字,并沒有再去執(zhí)行static WCBA wcba= new WCBA();充分說明了static只執(zhí)行一次。
顯示的靜態(tài)初始化
靜態(tài)塊也執(zhí)行一次,當(dāng)首次生成該類對(duì)象時(shí),或者首次訪問屬于那個(gè)類的靜態(tài)數(shù)據(jù)成員時(shí)。
class CBA{
CBA(String team){
System.out.println(team);
}
void f(){
System.out.println("CBA");
}
}
class NBA {
static CBA cba1;
static CBA cba2;
static{
cba1=new CBA("上海bilibili");
cba2=new CBA("上海bilibili2");
}
NBA(){
System.out.println("NBA構(gòu)造器");
}
}
public class Demo1 {
public static void main(String[] args) {
NBA.cba1.f();
//new NBA().cba1.f();這句話也行
}
}
輸出:
上海bilibili
上海bilibili2
CBA
非靜態(tài)實(shí)例初始化
用于初始化每個(gè)對(duì)象的非靜態(tài)變量
class CBA{
CBA(String team){
System.out.println(team);
}
void f(){
System.out.println("CBA");
}
}
class NBA {
CBA cba1;
CBA cba2;
{
cba1=new CBA("上海bilibili");
cba2=new CBA("上海bilibili2");
}
}
public class Demo1 {
public static void main(String[] args) {
new NBA().cba1.f();
new NBA().cba1.f();
}
}
輸出:
上海bilibili
上海bilibili2
CBA
上海bilibili
上海bilibili2
CBA
可以看到,{}塊每次都會(huì)執(zhí)行,而static{}只執(zhí)行一次。