Java枚舉
ava 5.0引入了枚舉掉冶,枚舉限制變量只能是預(yù)先設(shè)定好的值楼雹。使用枚舉可以減少代碼中的bug。
enum FreshJuiceSize {
SMALL("small"), MEDIUM("medium"), LARGE("large");
FreshJuiceSize(String a) {
this.a = a;
}
public String a() {
return a + 1;
}
public String a;
public static class A {
}
}
注意:枚舉可以單獨(dú)聲明或者聲明在類里面优床。方法劝赔、變量、構(gòu)造函數(shù)也可以在枚舉中定義胆敞。
Java 空行
空白行着帽,或者有注釋的行,Java編譯器都會(huì)忽略掉移层。
常用轉(zhuǎn)義字符
前面有反斜杠(\)的字符代表轉(zhuǎn)義字符仍翰,它對(duì)編譯器來說是有特殊含義的。
"\b" (退格) "\f" (換頁(yè)) "\n" (換行) "\r" (回車) "\t" (水平制表符(到下一個(gè)tab位置)) "' " (單引號(hào)) "" " (雙引號(hào)) "\" (反斜杠)
Linux中\(zhòng)n表示:回車+換行观话;
Windows中\(zhòng)r\n表示:回車+換行予借。
Mac中\(zhòng)r表示:回車+換行。
java的八種基本類型(按字節(jié)來分)
boolean 布爾型 1個(gè)字節(jié) 8bit(8位)
byte 字節(jié)類型 1個(gè)字節(jié)
char 字符類型 2個(gè)字節(jié)
short 短整型 2個(gè)字節(jié)
int 整型 4個(gè)字節(jié)
float 浮點(diǎn)型(單精度)4個(gè)字節(jié)
long 長(zhǎng)整型 8個(gè)字節(jié)
double 雙精度類型 8個(gè)字節(jié)
Java中默認(rèn)的整數(shù)類型是int频蛔,如果要定義為long 灵迫,則要在數(shù)值后加上L或者l
默認(rèn)的浮點(diǎn)型是雙精度浮點(diǎn),如果要定義float晦溪,則要在數(shù)值后面加上f或者F
一個(gè)字節(jié)等于8位瀑粥,1個(gè)字節(jié)等于256個(gè)數(shù)。2^8
一個(gè)英文字母或者阿拉伯?dāng)?shù)字占一個(gè)字節(jié)
一個(gè)漢字占2個(gè)字節(jié)
自動(dòng)類型轉(zhuǎn)換
整型三圆、實(shí)型(常量)狞换、字符型數(shù)據(jù)可以混合運(yùn)算。運(yùn)算中舟肉,不同類型的數(shù)據(jù)先轉(zhuǎn)化為同一類型修噪,然后進(jìn)行運(yùn)算。轉(zhuǎn)換從低級(jí)到高級(jí)路媚。
- 不能對(duì)boolean類型進(jìn)行類型轉(zhuǎn)換黄琼。
- 不能把對(duì)象類型轉(zhuǎn)換成不相關(guān)類的對(duì)象。
- 在把容量大的類型轉(zhuǎn)換為容量小的類型時(shí)必須使用強(qiáng)制類型轉(zhuǎn)換整慎。
- 轉(zhuǎn)換過程中可能導(dǎo)致溢出或損失精度
因?yàn)?byte 類型是 8 位适荣,最大值為127,所以當(dāng) int 強(qiáng)制轉(zhuǎn)換為 byte 類型時(shí)院领,值 128 時(shí)候就會(huì)導(dǎo)致溢出弛矛。 - 浮點(diǎn)數(shù)到整數(shù)的轉(zhuǎn)換是通過舍棄小數(shù)得到们童,而不是四舍五入
java局部變量
Java 局部變量
局部變量聲明在方法政勃、構(gòu)造方法或者語句塊中;
局部變量在方法宫纬、構(gòu)造方法强法、或者語句塊被執(zhí)行的時(shí)候創(chuàng)建万俗,當(dāng)它們執(zhí)行完成后,變量將會(huì)被銷毀饮怯;
訪問修飾符不能用于局部變量闰歪;
局部變量只在聲明它的方法、構(gòu)造方法或者語句塊中可見蓖墅;
局部變量是在棧上分配的库倘。
局部變量沒有默認(rèn)值临扮,所以局部變量被聲明后,必須經(jīng)過初始化教翩,才可以使用杆勇。
實(shí)例變量
實(shí)例變量聲明在一個(gè)類中,但在方法饱亿、構(gòu)造方法和語句塊之外蚜退;
當(dāng)一個(gè)對(duì)象被實(shí)例化之后,每個(gè)實(shí)例變量的值就跟著確定彪笼;
實(shí)例變量在對(duì)象創(chuàng)建的時(shí)候創(chuàng)建钻注,在對(duì)象被銷毀的時(shí)候銷毀;
實(shí)例變量的值應(yīng)該至少被一個(gè)方法配猫、構(gòu)造方法或者語句塊引用幅恋,使得外部能夠通過這些方式獲取實(shí)例變量信息;
實(shí)例變量可以聲明在使用前或者使用后章姓;
訪問修飾符可以修飾實(shí)例變量佳遣;
實(shí)例變量對(duì)于類中的方法、構(gòu)造方法或者語句塊是可見的凡伊。一般情況下應(yīng)該把實(shí)例變量設(shè)為私有零渐。通過使用訪問修飾符可以使實(shí)例變量對(duì)子類可見;
實(shí)例變量具有默認(rèn)值系忙。數(shù)值型變量的默認(rèn)值是0诵盼,布爾型變量的默認(rèn)值是false,引用類型變量的默認(rèn)值是null银还。變量的值可以在聲明時(shí)指定风宁,也可以在構(gòu)造方法中指定;
實(shí)例變量可以直接通過變量名訪問蛹疯。但在靜態(tài)方法以及其他類中戒财,就應(yīng)該使用完全限定名:ObejectReference.VariableName。
抽象方法
抽象方法不能被聲明成 final 和 static捺弦。
任何繼承抽象類的子類必須實(shí)現(xiàn)父類的所有抽象方法饮寞,除非該子類也是抽象類。
volatile 修飾符
volatile 修飾的成員變量在每次被線程訪問時(shí)列吼,都強(qiáng)制從共享內(nèi)存中重新讀取該成員變量的值幽崩。而且,當(dāng)成員變量發(fā)生變化時(shí)寞钥,會(huì)強(qiáng)制線程將變化值回寫到共享內(nèi)存慌申。這樣在任何時(shí)刻,兩個(gè)不同的線程總是看到某個(gè)成員變量的同一個(gè)值理郑。
一個(gè) volatile 對(duì)象引用可能是 null蹄溉。
transient 修飾符
序列化的對(duì)象包含被 transient 修飾的實(shí)例變量時(shí)咨油,java 虛擬機(jī)(JVM)跳過該特定的變量。
該修飾符包含在定義變量的語句中类缤,用來預(yù)處理類和變量的數(shù)據(jù)類型臼勉。
static和final
static不可以修飾外部類邻吭,可以修飾內(nèi)部類 餐弱,方法和全局變量
final可以修飾類,方法囱晴,變量(包括內(nèi)部變量)膏蚓。final 修飾屬性,聲明變量時(shí)可以不賦值畸写,而且一旦賦值就不能被修改了驮瞧。對(duì) final 屬性可以在三個(gè)地方賦值:聲明時(shí)、初始化塊中枯芬、構(gòu)造方法中论笔,總之一定要賦值。
final 變量:
final 變量能被顯式地初始化并且只能初始化一次千所。被聲明為 final 的對(duì)象的引用不能指向不同的對(duì)象狂魔。但是 final 對(duì)象里的數(shù)據(jù)可以被改變。也就是說 final 對(duì)象的引用不能改變淫痰,但是里面的值可以改變最楷。
final 方法:
類中的 final 方法可以被子類繼承,但是不能被子類修改待错。
final 類:
final 類不能被繼承籽孙,沒有類能夠繼承 final 類的任何特性。
自增自減運(yùn)算符
1火俄、自增(++)自減(--)運(yùn)算符是一種特殊的算術(shù)運(yùn)算符犯建,在算術(shù)運(yùn)算符中需要兩個(gè)操作數(shù)來進(jìn)行運(yùn)算,而自增自減運(yùn)算符是一個(gè)操作數(shù)瓜客。
2适瓦、前綴自增自減法(++a,--a): 先進(jìn)行自增或者自減運(yùn)算,再進(jìn)行表達(dá)式運(yùn)算忆家。
3犹菇、后綴自增自減法(a++,a--): 先進(jìn)行表達(dá)式運(yùn)算,再進(jìn)行自增或者自減運(yùn)算
while 循環(huán)和do…while 循環(huán)
對(duì)于 while 語句而言芽卿,如果不滿足條件揭芍,則不能進(jìn)入循環(huán)。但有時(shí)候我們需要即使不滿足條件卸例,也至少執(zhí)行一次称杨。do…while 循環(huán)和 while 循環(huán)相似肌毅,不同的是,do…while 循環(huán)至少會(huì)執(zhí)行一次姑原。
continue 關(guān)鍵字
continue 適用于任何循環(huán)控制結(jié)構(gòu)中悬而。作用是讓程序立刻跳轉(zhuǎn)到下一次循環(huán)的迭代。
在 for 循環(huán)中锭汛,continue 語句使程序立即跳轉(zhuǎn)到更新語句笨奠。
在 while 或者 do…while 循環(huán)中,程序立即跳轉(zhuǎn)到布爾表達(dá)式的判斷語句唤殴。
if...else if...else 語句
if 語句后面可以跟 elseif…else 語句般婆,這種語句可以檢測(cè)到多種可能的情況。
使用 if朵逝,else if蔚袍,else 語句的時(shí)候,需要注意下面幾點(diǎn):
if 語句至多有 1 個(gè) else 語句配名,else 語句在所有的 elseif 語句之后啤咽。
if 語句可以有若干個(gè) elseif 語句,它們必須在 else 語句之前渠脉。
一旦其中一個(gè) else if 語句檢測(cè)為 true宇整,其他的 else if 以及 else 語句都將跳過執(zhí)行。
switch 語句
switch 語句中的變量類型可以是:char,byte,short,int,Character,Byte,Short,Integer,String,enum
Integer
對(duì)于–128到127(默認(rèn)是127)之間的值,被裝箱后连舍,會(huì)被放在內(nèi)存里進(jìn)行重用,但是如果超出了這個(gè)值,系統(tǒng)會(huì)重新new 一個(gè)對(duì)象
Integer a = 10;
Integer b = 10;
System.out.println(a == b); // true
System.out.println(a.equals(b)); // true
Integer a = 1000;
Integer b = 1000;
System.out.println(a == b); // false
System.out.println(a.equals(b)); // true
Math類的個(gè)別方法
ceil():返回大于等于( >= )給定參數(shù)的的最小整數(shù)没陡。
floor():返回小于等于(<=)給定參數(shù)的最大整數(shù) 。
rint():返回與參數(shù)最接近的整數(shù)索赏。返回類型為double盼玄。
round():它表示四舍五入,算法為 Math.floor(x+0.5)潜腻,即將原來的數(shù)字加上 0.5 后再向下取整埃儿,所以,Math.round(11.5) 的結(jié)果為12融涣,Math.round(-11.5) 的結(jié)果為-11童番。
String
:String 類是不可改變的,所以你一旦創(chuàng)建了 String 對(duì)象威鹿,那它的值就無法改變了剃斧。如果需要對(duì)字符串做很多修改,那么應(yīng)該選擇使用 StringBuffer & StringBuilder 類忽你。
String 類是不可改變的解析幼东,例如:
String s = "Google";
System.out.println("s = " + s);
s = "Runoob";
System.out.println("s = " + s);
輸出結(jié)果為:
Google
Runoob
從結(jié)果上看是改變了,但為什么門說String對(duì)象是不可變的呢?
原因在于實(shí)例中的 s 只是一個(gè) String 對(duì)象的引用根蟹,并不是對(duì)象本身脓杉,當(dāng)執(zhí)行 s = "Runoob"; 創(chuàng)建了一個(gè)新的對(duì)象 "Runoob",而原來的 "Google" 還存在于內(nèi)存中简逮。
Java StringBuffer 和 StringBuilder 類
當(dāng)對(duì)字符串進(jìn)行修改的時(shí)候球散,需要使用 StringBuffer 和 StringBuilder 類。
和 String 類不同的是散庶,StringBuffer 和 StringBuilder 類的對(duì)象能夠被多次的修改蕉堰,并且不產(chǎn)生新的未使用對(duì)象。
StringBuilder 類在 Java 5 中被提出督赤,它和 StringBuffer 之間的最大不同在于 StringBuilder 的方法不是線程安全的(不能同步訪問)嘁灯。
由于 StringBuilder 相較于 StringBuffer 有速度優(yōu)勢(shì)泻蚊,所以多數(shù)情況下建議使用 StringBuilder 類躲舌。然而在應(yīng)用程序要求線程安全的情況下,則必須使用 StringBuffer 類性雄。
Arrays 類
java.util.Arrays 類能方便地操作數(shù)組没卸,它提供的所有方法都是靜態(tài)的。
具有以下功能:
給數(shù)組賦值:通過 fill 方法秒旋。
對(duì)數(shù)組排序:通過 sort 方法,按升序约计。
比較數(shù)組:通過 equals 方法比較數(shù)組中元素值是否相等。
查找數(shù)組元素:通過 binarySearch 方法能對(duì)排序好的數(shù)組進(jìn)行二分查找法操作迁筛。
使用printf格式化日期
printf 方法可以很輕松地格式化時(shí)間和日期煤蚌。使用兩個(gè)字母格式,它以 %t 開頭并且以下面表格中的一個(gè)字母結(jié)尾细卧。
import java.util.Date;
public class DateDemo {
public static void main(String args[]) {
// 初始化 Date 對(duì)象
Date date = new Date();
//c的使用
System.out.printf("全部日期和時(shí)間信息:%tc%n",date);
//f的使用
System.out.printf("年-月-日格式:%tF%n",date);
//d的使用
System.out.printf("月/日/年格式:%tD%n",date);
//r的使用
System.out.printf("HH:MM:SS PM格式(12時(shí)制):%tr%n",date);
//t的使用
System.out.printf("HH:MM:SS格式(24時(shí)制):%tT%n",date);
//R的使用
System.out.printf("HH:MM格式(24時(shí)制):%tR",date);
}
}
可變參數(shù)
JDK 1.5 開始尉桩,Java支持傳遞同類型的可變參數(shù)給一個(gè)方法。
方法的可變參數(shù)的聲明如下所示:
typeName... parameterName
在方法聲明中贪庙,在指定參數(shù)類型后加一個(gè)省略號(hào)(...) 蜘犁。
一個(gè)方法中只能指定一個(gè)可變參數(shù),它必須是方法的最后一個(gè)參數(shù)止邮。任何普通的參數(shù)必須在它之前聲明这橙。
public static void printMax( double... numbers) {
if (numbers.length == 0) {
System.out.println("No argument passed");
return;
}
double result = numbers[0];
for (int i = 1; i < numbers.length; i++){
if (numbers[i] > result) {
result = numbers[i];
}
}
System.out.println("The max value is " + result);
}
finalize() 方法
Java 允許定義這樣的方法,它在對(duì)象被垃圾收集器析構(gòu)(回收)之前調(diào)用导披,這個(gè)方法叫做 finalize( )屈扎,它用來清除回收對(duì)象。
例如撩匕,你可以使用 finalize() 來確保一個(gè)對(duì)象打開的文件被關(guān)閉了鹰晨。
在 finalize() 方法里,你必須指定在對(duì)象銷毀時(shí)候要執(zhí)行的操作。
finalize() 一般格式是:
protected void finalize()
{
// 在這里終結(jié)代碼
}
關(guān)鍵字 protected 是一個(gè)限定符并村,它確保 finalize() 方法不會(huì)被該類以外的代碼調(diào)用巍实。
當(dāng)然,Java 的內(nèi)存回收可以由 JVM 來自動(dòng)完成哩牍。如果你手動(dòng)使用棚潦,則可以使用上面的方法。
注:當(dāng)我們調(diào)用System.gc()的時(shí)候膝昆,其實(shí)并不會(huì)馬上進(jìn)行垃圾回收丸边,甚至不一定會(huì)執(zhí)行垃圾回收。查看ZygoteInit.java 里面 gc()和runFinalizationSync()是配合使用才有效果
java流
throw與throws的比較
1荚孵、throws出現(xiàn)在方法函數(shù)頭妹窖;而throw出現(xiàn)在函數(shù)體。
2收叶、throws表示出現(xiàn)異常的一種可能性骄呼,并不一定會(huì)發(fā)生這些異常;throw則是拋出了異常判没,執(zhí)行throw則一定拋出了某種異常對(duì)象蜓萄。
3、兩者都是消極處理異常的方式(這里的消極并不是說這種方式不好)澄峰,只是拋出或者可能拋出異常嫉沽,但是不會(huì)由函數(shù)去處理異常,真正的處理異常由函數(shù)的上層調(diào)用處理俏竞。
try/catch/finally
catch 不能獨(dú)立于 try 存在绸硕。
在 try/catch 后面添加 finally 塊并非強(qiáng)制性要求的。
try 代碼后不能既沒 catch 塊也沒 finally 塊魂毁。
try, catch, finally 塊之間不能添加任何代碼玻佩。
try{
//待捕獲代碼
}catch(Exception e){
System.out.println("catch is begin");
return 1 ;
}finally{
System.out.println("finally is begin");
}
//運(yùn)行結(jié)果如下:
catch is begin
finally is begin
也就是說會(huì)先執(zhí)行catch里面的代碼后執(zhí)行finally里面的代碼最后才return1 漱牵;再看如下代碼:
try{
//待捕獲代碼
}catch(Exception e){
System.out.println("catch is begin");
return 1 夺蛇;
}finally{
System.out.println("finally is begin");
return 2 ;
}
這段代碼中輸出結(jié)果跟上段是一樣的,然而返回的是return 2 酣胀;原因很明顯刁赦,就是執(zhí)行了finally后已經(jīng)return了,所以catch里面的return不會(huì)被執(zhí)行到闻镶。也就是說finally永遠(yuǎn)都會(huì)在catch的return前被執(zhí)行甚脉。catch和finally中的system.out都會(huì)輸出,但是catch中的system.out優(yōu)先于finally的system.out輸出铆农。
通用異常
JVM(Java虛擬機(jī)) 異常:由 JVM 拋出的異澄保或錯(cuò)誤狡耻。例如:NullPointerException 類,ArrayIndexOutOfBoundsException 類猴凹,ClassCastException 類夷狰。
繼承
利用繼承的方法,可以重用已存在類的方法和屬性书劝,而不用重寫這些代碼进倍。
子類可以繼承父類的靜態(tài)方法,子類不可以復(fù)寫父類的靜態(tài)方法和final修飾的方法
子類擁有父類非private的屬性购对,方法猾昆。
子類可以擁有自己的屬性和方法,即子類可以對(duì)父類進(jìn)行擴(kuò)展骡苞。
子類可以用自己的方式實(shí)現(xiàn)父類的方法垂蜗。
Java的繼承是單繼承,但是可以多重繼承烙如,單繼承就是一個(gè)子類只能繼承一個(gè)父類么抗,多重繼承就是,例如A類繼承B類亚铁,B類繼承C類,所以按照關(guān)系就是C類是B類的父類螟加,B類是A類的父類徘溢,這是java繼承區(qū)別于C++繼承的一個(gè)特性。
提高了類之間的耦合性(繼承的缺點(diǎn)捆探,耦合度高就會(huì)造成代碼之間的聯(lián)系)然爆。
super 與 this 關(guān)鍵字
super關(guān)鍵字:我們可以通過super關(guān)鍵字來實(shí)現(xiàn)對(duì)父類成員的訪問,用來引用當(dāng)前對(duì)象的父類黍图。靜態(tài)方法中不能使用 super 關(guān)鍵字曾雕。super 語句必須是子類構(gòu)造方法的第一條語句。如果是繼承的方法助被,是沒有必要使用 super 來調(diào)用剖张,直接即可調(diào)用。但如果子類覆蓋或重寫了父類的方法揩环,則只有使用 super 才能在子類中調(diào)用父類中的被重寫的方法搔弄。
this關(guān)鍵字:指向自己的引用。用當(dāng)前類的構(gòu)造方法丰滑,并且必須是方法的第一條語句顾犹。如:this(); 調(diào)用默認(rèn)構(gòu)造方法。this(參數(shù)); 調(diào)用帶參構(gòu)造方法。限定當(dāng)前對(duì)象的數(shù)據(jù)域變量炫刷。一般用于方法內(nèi)的局部變量與對(duì)象的數(shù)據(jù)域變量同名的情況擎宝。如 this.num = num。this.num 表示當(dāng)前對(duì)象的數(shù)據(jù)域變量 num浑玛,而 num 表示方法中的局部變量认臊。
構(gòu)造器
子類不能繼承父類的構(gòu)造器(構(gòu)造方法或者構(gòu)造函數(shù)),但是父類的構(gòu)造器帶有參數(shù)的锄奢,則必須在子類的構(gòu)造器中顯式地通過super關(guān)鍵字調(diào)用父類的構(gòu)造器并配以適當(dāng)?shù)膮?shù)列表失晴。
如果父類有無參構(gòu)造器,則在子類的構(gòu)造器中用super調(diào)用父類構(gòu)造器不是必須的拘央,如果沒有使用super關(guān)鍵字涂屁,系統(tǒng)會(huì)自動(dòng)調(diào)用父類的無參構(gòu)造器。
方法的重寫規(guī)則
參數(shù)列表必須完全與被重寫方法的相同灰伟;
返回類型必須完全與被重寫方法的返回類型相同拆又;
訪問權(quán)限不能比父類中被重寫的方法的訪問權(quán)限更低。例如:如果父類的一個(gè)方法被聲明為public栏账,那么在子類中重寫該方法就不能聲明為protected帖族。
父類的成員方法只能被它的子類重寫。
聲明為final的方法不能被重寫挡爵。
聲明為static的方法不能被重寫竖般,但是能夠被再次聲明。
子類和父類在同一個(gè)包中茶鹃,那么子類可以重寫父類所有方法涣雕,除了聲明為private和final的方法。
子類和父類不在同一個(gè)包中闭翩,那么子類只能夠重寫父類的聲明為public和protected的非final方法挣郭。
重寫的方法能夠拋出任何非強(qiáng)制異常,無論被重寫的方法是否拋出異常疗韵。但是兑障,重寫的方法不能拋出新的強(qiáng)制性異常,或者比被重寫方法聲明的更廣泛的強(qiáng)制性異常蕉汪,反之則可以流译。
構(gòu)造方法不能被重寫。
如果不能繼承一個(gè)方法肤无,則不能重寫這個(gè)方法先蒋。
方法重載
最常用的地方就是構(gòu)造器的重載。
被重載的方法必須改變參數(shù)列表(參數(shù)個(gè)數(shù)或類型或順序不一樣)宛渐;
被重載的方法可以改變返回類型竞漾;
被重載的方法可以改變?cè)L問修飾符眯搭;
被重載的方法可以聲明新的或更廣的檢查異常;
方法能夠在同一個(gè)類中或者在一個(gè)子類中被重載业岁。
無法以返回值類型作為重載函數(shù)的區(qū)分標(biāo)準(zhǔn)鳞仙。
重載和重寫的區(qū)別
java多態(tài)
必要條件:繼承、重寫笔时、父類引用指向子類對(duì)象
多態(tài)的優(yōu)點(diǎn):1. 消除類型之間的耦合關(guān)系 2. 可替換性 3. 可擴(kuò)充性 4. 接口性 5. 靈活性 6. 簡(jiǎn)化性
虛方法:多態(tài)是父類引用指向子類對(duì)象棍好,所以在編譯的時(shí)候,編譯器使用父類中的方法驗(yàn)證該語句允耿,如果父類沒有此方法則編譯不通過借笙, 但是在運(yùn)行的時(shí)候,Java虛擬機(jī)(JVM)調(diào)用的是子類中的 方法较锡。
class Animal{
public int age;
public void move(){
System.out.println("動(dòng)物可以移動(dòng)");
}
}
class Dog extends Animal{
public double age;
public void move(){
age = 10.00;
System.out.println("狗可以跑和走");
}
public void bark(){
System.out.println("狗可以吠叫");
}
}
class Cat extends Animal{
public void move(){
super.age = 3;
System.out.println("貓可以跳");
}
}
public class TestOverride{
public static void main(String args[]){
Animal a = new Animal(); // Animal 對(duì)象
Animal b = new Dog(); // Dog 對(duì)象
Dog c = new Dog();
Cat d = new Cat();
a.move();// 執(zhí)行 Animal 類的方法
b.move();//執(zhí)行 Dog 類的方法
c.move();//執(zhí)行 Dog 類的方法
d.move();//執(zhí)行 Cat 類的方法
Object aValue = a.age;
Object bValue = b.age;
Object cValue = c.age;
System.out.println("The type of "+a.age+" is "+(aValue instanceof Double ? "double" : (aValue instanceof Integer ? "int" : "")));
System.out.println("The type of "+b.age+" is "+(bValue instanceof Double ? "double" : (bValue instanceof Integer ? "int" : "")));
System.out.println("The type of "+c.age+" is "+(cValue instanceof Double ? "double" : (cValue instanceof Integer ? "int" : "")));// 覆蓋age屬性
System.out.println("The age of cat is "+d.age);
}
}
//結(jié)果
//動(dòng)物可以移動(dòng)
//狗可以跑和走
//狗可以跑和走
//貓可以跳
//The type of 0 is int
//The type of 0 is int
//The type of 10.0 is double
//The age of cat is 3
java抽象類
由于抽象類不能實(shí)例化對(duì)象业稼,所以抽象類必須被繼承,才能被使用蚂蕴。也是因?yàn)檫@個(gè)原因低散,通常在設(shè)計(jì)階段決定要不要設(shè)計(jì)抽象類。(代碼表現(xiàn)形式上看沒有抽象方法的抽象類是不可以new出來的骡楼。帶有抽象方法的抽象類new出來的時(shí)候要實(shí)現(xiàn)抽象方法)
java封裝
封裝最主要的功能在于我們能修改自己的實(shí)現(xiàn)代碼熔号,而不用修改那些調(diào)用我們代碼的程序片段。
適當(dāng)?shù)姆庋b可以讓程式碼更容易理解與維護(hù)鸟整,也加強(qiáng)了程式碼的安全性引镊。
優(yōu)點(diǎn):1. 良好的封裝能夠減少耦合。 2. 類內(nèi)部的結(jié)構(gòu)可以自由修改吃嘿。 3. 可以對(duì)成員變量進(jìn)行更精確的控制祠乃。 4. 隱藏信息,實(shí)現(xiàn)細(xì)節(jié)兑燥。
接口
接口中每一個(gè)方法也是隱式抽象的,接口中的方法會(huì)被隱式的指定為 public abstract(只能是 public abstract,其他修飾符都會(huì)報(bào)錯(cuò))琴拧。
接口中可以含有變量降瞳,但是接口中的變量會(huì)被隱式的指定為 public static final 變量(并且只能是 public,用 private 修飾會(huì)報(bào)編譯錯(cuò)誤)蚓胸。
接口中的方法是不能在接口中實(shí)現(xiàn)的挣饥,只能由實(shí)現(xiàn)接口的類來實(shí)現(xiàn)接口中的方法。
一個(gè)接口能繼承另一個(gè)接口沛膳,這和類之間的繼承比較相似扔枫。
在 JDK1.8,允許我們給接口添加兩種非抽象的方法實(shí)現(xiàn):
1锹安、默認(rèn)方法短荐,添加 default 修飾即可倚舀;
2、靜態(tài)方法忍宋,使用 static 修飾痕貌;示例如下:
interface Test{
//這個(gè)是默認(rèn)方法
default String get(String aa){
System.out.println("我是jdk1.8默認(rèn)實(shí)現(xiàn)方法...");
return "";
}
//這個(gè)是靜態(tài)方法
static void staticmethod(){
System.out.println("我是靜態(tài)方法");
}
}
接口和類的區(qū)別:1.接口不能用于實(shí)例化對(duì)象。 2.接口沒有構(gòu)造方法糠排。 3.接口中所有的方法必須是抽象方法舵稠。 4.接口不能包含成員變量,除了 static 和 final 變量入宦。 5.接口不是被類繼承了哺徊,而是要被類實(shí)現(xiàn)。 6.接口支持多繼承乾闰。
接口中不能含有靜態(tài)代碼塊以及靜態(tài)方法(用 static 修飾的方法)落追,而抽象類是可以有靜態(tài)代碼塊和靜態(tài)方法。
接口的多繼承
在Java中汹忠,類的多繼承是不合法淋硝,但接口允許多繼承,宽菜。
在接口的多繼承中extends關(guān)鍵字只需要使用一次谣膳,在其后跟著繼承接口。 如下所示:
public interface Impl2 extends Impl1,Impl {}
標(biāo)記接口
最常用的繼承接口是沒有包含任何方法的接口铅乡。
標(biāo)記接口是沒有任何方法和屬性的接口.它僅僅表明它的類屬于一個(gè)特定的類型,供其他代碼來測(cè)試允許做一些事情继谚。
標(biāo)記接口作用:簡(jiǎn)單形象的說就是給某個(gè)對(duì)象打個(gè)標(biāo)(蓋個(gè)戳),使對(duì)象擁有某個(gè)或某些特權(quán)阵幸。
例如:java.awt.event 包中的 MouseListener 接口繼承的 java.util.EventListener 接口定義如下:
package java.util;
public interface EventListener{}
package(包)
如果在一個(gè)包中花履,一個(gè)類想要使用本包中的另一個(gè)類,那么該包名可以省略挚赊。
JVM加載class文件的原理機(jī)制
JVM中類的裝載是由類加載器(ClassLoader)和它的子類來實(shí)現(xiàn)的诡壁,Java中的類加載器是一個(gè)重要的Java運(yùn)行時(shí)系統(tǒng)組件,它負(fù)責(zé)在運(yùn)行時(shí)查找和裝入類文件中的類荠割。
由于Java的跨平臺(tái)性妹卿,經(jīng)過編譯的Java源程序并不是一個(gè)可執(zhí)行程序,而是一個(gè)或多個(gè)類文件蔑鹦。當(dāng)Java程序需要使用某個(gè)類時(shí)夺克,JVM會(huì)確保這個(gè)類已經(jīng)被加載、連接(驗(yàn)證嚎朽、準(zhǔn)備和解析)和初始化铺纽。類的加載是指把類的.class文件中的數(shù)據(jù)讀入到內(nèi)存中,通常是創(chuàng)建一個(gè)字節(jié)數(shù)組讀入.class文件哟忍,然后產(chǎn)生與所加載類對(duì)應(yīng)的Class對(duì)象狡门。加載完成后陷寝,Class對(duì)象還不完整,所以此時(shí)的類還不可用融撞。當(dāng)類被加載后就進(jìn)入連接階段盼铁,這一階段包括驗(yàn)證、準(zhǔn)備(為靜態(tài)變量分配內(nèi)存并設(shè)置默認(rèn)的初始值)和解析(將符號(hào)引用替換為直接引用)三個(gè)步驟尝偎。最后JVM對(duì)類進(jìn)行初始化饶火,包括:1)如果類存在直接的父類并且這個(gè)類還沒有被初始化,那么就先初始化父類致扯;2)如果類中存在初始化語句肤寝,就依次執(zhí)行這些初始化語句。
類的加載是由類加載器完成的抖僵,類加載器包括:根加載器(BootStrap)鲤看、擴(kuò)展加載器(Extension)、系統(tǒng)加載器(System)和用戶自定義類加載器(java.lang.ClassLoader的子類)耍群。從Java 2(JDK 1.2)開始义桂,類加載過程采取了父親委托機(jī)制(PDM)。PDM更好的保證了Java平臺(tái)的安全性蹈垢,在該機(jī)制中慷吊,JVM自帶的Bootstrap是根加載器,其他的加載器都有且僅有一個(gè)父類加載器曹抬。類的加載首先請(qǐng)求父類加載器加載溉瓶,父類加載器無能為力時(shí)才由其子類加載器自行加載。JVM不會(huì)向Java程序提供對(duì)Bootstrap的引用谤民。
Java泛型:http://www.reibang.com/p/c6321a76fb8a
后續(xù)會(huì)整理一些java高級(jí)的部分堰酿!
錯(cuò)誤不足之處或相關(guān)建議歡迎大家評(píng)論指出,謝謝张足!如果覺得內(nèi)容可以的話麻煩喜歡(?)一下