面向?qū)ο螅ㄏ拢?/h1>
6.1 java8增強(qiáng)的包裝類(lèi)
int Integer
char Character
其他的都是直接首字母變大寫(xiě)
可以自動(dòng)裝箱纸泡,自動(dòng)拆箱。
如果int想變成Integer,直接賦值給一個(gè)Integer 變量就行赖瞒。
如果Integer想變成int,直接賦值給一個(gè)int變量就行田绑。
基本類(lèi)型和字符串之間的轉(zhuǎn)換方法
- 字符串轉(zhuǎn)換成基本類(lèi)型
int i=Integer.parseInt(str);
或者
int i=new Integer(str); - 基本類(lèi)型轉(zhuǎn)換成字符串
String flStr=String.valueOf(float變量)抡爹;
或者
String flStr=float變量+“”冬竟;
包裝類(lèi)比較大小
- 如果直接給integer數(shù)字,如果數(shù)字在-128-127之間涮帘,則兩個(gè)數(shù)字相等笑诅,包裝類(lèi)相等疮鲫。
- 如果用new integer(2)賦值弦叶,則必須兩個(gè)包裝類(lèi)指向同一個(gè)對(duì)象才相等伤哺。
- 有一個(gè)Integer.compare(a,b)可以直接用來(lái)比較包裝類(lèi)大小.
a>b 返回1
a=b 返回0
a<b 返回-1
6.2 處理對(duì)象
6.2.1 打印對(duì)象和toString方法
toString方法
toString () 是Object類(lèi)里面的一個(gè)實(shí)例方法,所有對(duì)象都具有這個(gè)方法绢彤。
系統(tǒng)自帶的tostring“類(lèi)名+@+hashcode”
可以自己重寫(xiě)這個(gè)方法蜓耻。
6.2.2 ==和equals方法
“==”
- 對(duì)于基本類(lèi)型的數(shù)值類(lèi)型(包括char),只要兩個(gè)變量的值相等奇适,返回true芦鳍。
- 對(duì)于引用類(lèi)型柠衅,必須指向同一個(gè)對(duì)象籍琳,才返回true。
注意:“==“不能用于比較沒(méi)有父子關(guān)系的兩個(gè)對(duì)象喝峦。
”hello“直接量和new String (“hello”)區(qū)別
直接使用hello這種可以在編譯時(shí)候計(jì)算出來(lái)的字符串值呜达,jvm會(huì)用常量池來(lái)管理查近。jvm會(huì)保證相同的字符串直接量只有一個(gè),不會(huì)產(chǎn)生多個(gè)副本谈喳。
第二種戈泼,jvm會(huì)先用常量池來(lái)管理直接量赏僧,再調(diào)用string構(gòu)造器來(lái)創(chuàng)建 i 個(gè)新的string對(duì)象次哈。新創(chuàng)建的對(duì)象保存在堆中
equals()
equals()方法可以用來(lái)判斷字符串的內(nèi)容是否相等吆录。
但是當(dāng)用于對(duì)象時(shí),仍然必須是指向同一個(gè)對(duì)象才能夠返回true哀卫。
一般需要重寫(xiě)equals()撬槽。
- 首先判斷是否是同一個(gè)對(duì)象
- 如果不是同一個(gè)對(duì)象侄柔,在判斷是否是同一個(gè)類(lèi)型
- 如果是的話,把object轉(zhuǎn)化為目標(biāo)類(lèi)型移剪,采用equals方法比較內(nèi)容薪者。
6.3 類(lèi)成員
6.3.1 理解類(lèi)成員
類(lèi)成員就是用static修飾的成員變量,方法攻人,初始化塊悬槽,內(nèi)部類(lèi)的統(tǒng)稱初婆。能通過(guò)對(duì)象訪問(wèn)這些類(lèi)成員。即使對(duì)象是null 渣窜。類(lèi)成員不能訪問(wèn)實(shí)例成員宪躯,因?yàn)轭?lèi)成員的作用域更大访雪,可能類(lèi)成員還存在掂林,但是成員變量已經(jīng)不存在了坝橡,所以不能夠訪問(wèn)實(shí)例成員。
6.3.2 單例類(lèi)
一個(gè)類(lèi)始終只能創(chuàng)建一個(gè)實(shí)例锣杂,稱為單例類(lèi)元莫。
如果不想讓別的類(lèi)輕易的創(chuàng)建該類(lèi)的對(duì)象蝶押,就需要把類(lèi)的構(gòu)造函數(shù)設(shè)置成private,但是這個(gè)時(shí)候就需要有一個(gè)方法來(lái)創(chuàng)建一個(gè)對(duì)象,由于使用這個(gè)方法的時(shí)候還沒(méi)有對(duì)象茎截,因此需要給方法是static的赶盔。
同時(shí)招刨。為了滿足只能創(chuàng)建一個(gè)對(duì)象,則必須把已經(jīng)創(chuàng)建的對(duì)象保存起來(lái),每次創(chuàng)建對(duì)象之前都檢查一下是否只有一個(gè)對(duì)象杉适。由于存儲(chǔ)對(duì)象的成員變量需要通過(guò)上面的static方法調(diào)用猿推,因此需要設(shè)置為static。
package demo6;
public class Singleton {
//定義一個(gè)類(lèi)變量用來(lái)保存創(chuàng)建出來(lái)的對(duì)象
private static Singleton instance;
private Singleton(){}
//定義一個(gè)能夠返回對(duì)象的方法
public static Singleton getSingleton()
{
if(instance==null)
{
instance=new Singleton();
}
return instance;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Singleton s1=Singleton.getSingleton();
Singleton s2=Singleton.getSingleton();
System.out.print(s1==s2);
}
}
6.4 final修飾符
final修飾變量時(shí)候表示該變量一旦獲得了初始值藕咏,就無(wú)法再改變孽查。
6.4.1 final成員變量
類(lèi)變量:在靜態(tài)初始化塊或者聲明該變量時(shí)初始化
實(shí)例變量:在普通初始化塊坦喘,或者聲明該變量時(shí)候西设,或者構(gòu)造器贷揽。如果已經(jīng)在普通初始化塊賦值梦碗,則不可以再在構(gòu)造器中賦值洪规。
注意?:普通方法不能訪問(wèn)final修飾的成員變量。
final修飾的成員變量必須程序員自己顯示初始化淹冰,系統(tǒng)不會(huì)默認(rèn)賦值樱拴。
6.4.2 final局部變量
因?yàn)橄到y(tǒng)不會(huì)給局部變量初始化,因此在用final修飾的局部變量不一定非由程序員顯示初始化珍坊。
方法中的形參不能夠在方法里面初始化正罢,因?yàn)樾螀⒌某跏蓟窃诒徽{(diào)用的時(shí)候由實(shí)參傳入的翻具。
6.4.3 final修飾基本類(lèi)型變量和引用類(lèi)型變量的區(qū)別
final修飾基本類(lèi)型變量,就不能更改值了叹洲。如果是引用類(lèi)型工禾,則只要不改變地址就行,里面的內(nèi)容可以隨意
package demo6;
import java.util.Arrays;
class Person1
{
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Person1() {}
public Person1(int age)
{
this.age=age;
}
}
public class FinalReferenceTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
//可以無(wú)限的更改數(shù)組里面的內(nèi)容民泵,但是不能夠更改數(shù)組的地址
final int[] iArr={3,4,5,6};
iArr[2]=19;
System.out.print(Arrays.toString(iArr));
Arrays.sort(iArr);
System.out.println(Arrays.toString(iArr));
//iArr=null;
Person1 p1=new Person1();
p1.setAge(7);
//這里竟然可以更改栈妆,,掏呼,铅檩,昧旨,不懂不懂
p1=null;
System.out.print(iArr);
}
}
6.4.4 可執(zhí)行“宏替換”的final變量
變量滿足三個(gè)條件,則變量相當(dāng)于一個(gè)直接量
- final修飾
- 在定義的時(shí)候指定了初始值(只有在定義的時(shí)候賦值才有這種效果)
- 值可以在編譯的時(shí)候確定下來(lái)
6.4.5 final 方法
final方法不能夠被重寫(xiě)蒋得。如果父類(lèi)的方法不希望子類(lèi)重寫(xiě)乒疏,只要加上final 就好怕吴。
但是父類(lèi)的private 是不會(huì)被子類(lèi)繼承的,因此也不會(huì)有重寫(xiě)這個(gè)說(shuō)法伟件。因此如果父類(lèi)的private方法被final了议经,子類(lèi)仍然可以寫(xiě)一個(gè)一樣的方法煞肾。
6.4.6 final類(lèi)
不能有子類(lèi)的類(lèi)
6.4.7 不可變類(lèi)
不可變類(lèi)是創(chuàng)建該類(lèi)的實(shí)例后,實(shí)例變量不能夠更改拯爽。
創(chuàng)建自定義的不可變類(lèi)方法:
1钧忽,類(lèi)的成員變量用private和final修飾
2耸黑,提供帶參數(shù)的構(gòu)造函數(shù)篮幢,用于根據(jù)傳入?yún)?shù)來(lái)初始化類(lèi)的成員變量
3,該類(lèi)僅有g(shù)etter
4缺菌,重新定義equals()和hashcode()
package demo6;
public class Address {
private final String detail;
private final String postCode;
public Address()
{
this.detail="";
this.postCode="";
}
public Address(String detail,String postCode)
{
this.detail=detail;
this.postCode=postCode;
}
public String getDetail()
{
return detail;
}
public String getPostCode()
{
return postCode;
}
public boolean equals(Object obj)
{
if(obj==this)
{
return true;
}
if(obj!=null&&obj.getClass().equals(Address.class))
{
Address AddObj=(Address)obj;
if(AddObj.getDetail().equals(this.getDetail()))
{
return true;
}
}
return false;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
當(dāng)創(chuàng)建不可變類(lèi)的時(shí)候伴郁,如果成員變量里面有引用類(lèi)型,則很可能創(chuàng)建出一個(gè)可變類(lèi)剂陡,因?yàn)槌蓡T變量的內(nèi)容可以更改鸭栖。必須采用一些其他的方法握巢,才能創(chuàng)建真正的不可變類(lèi)。
6.4.8 緩存實(shí)例的不可變類(lèi)
緩存實(shí)例的不可變類(lèi)溅话,是因?yàn)橛械臅r(shí)候一個(gè)對(duì)象的某個(gè)成員被多次引用肉渴,為了節(jié)省開(kāi)銷(xiāo)同规,可以把它緩存起來(lái)。下邊是把它緩存在數(shù)組里面绪钥,如果緩存里面已經(jīng)有了关炼,就直接返回實(shí)例儒拂,如果沒(méi)有,就新建實(shí)例加進(jìn)去见转。
package demo6;
//這個(gè)類(lèi)主要是弄一個(gè)數(shù)組蒜哀,然后緩存string數(shù)據(jù)
class CacheInnutale
{
private static int MAX_SIZE;
private static CacheInnutale[] cache=new CacheInnutale[MAX_SIZE];
//pos為什么要是static
private static int pos=0;
private final String name;
public String getName() {
return name;
}
private CacheInnutale(String name)
{
this.name=name;
}
// 使用數(shù)組緩存已有的實(shí)例,并且記錄緩存的位置
public static CacheInnutale valueOf(String name)
{
//遍歷已經(jīng)緩存的對(duì)象狐血,如果有相同的易核,直接返回緩存的實(shí)例
for(int i=0;i<name.length();i++)
{
if(name!=null&&cache[i].getName().equals(name))
{
return cache[i];
}
}
//如果緩存已經(jīng)滿了耸成,則從頭開(kāi)始緩存
if(MAX_SIZE==pos)
{
cache[0]=new CacheInnutale(name);
pos=1;
}
//緩存沒(méi)滿的話,把新建的對(duì)象緩存起來(lái)
else
{
cache[pos++]=new CacheInnutale(name);
}
//因?yàn)槭呛?弦追,所以pos-1
return cache[pos-1];
}
}
public class CacheInnutaleTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
6.5 抽象類(lèi)
抽象方法是只有方法的簽名花竞,沒(méi)有方法的實(shí)現(xiàn)
6.5.1 抽象方法和抽象類(lèi)
抽象方法和抽象類(lèi)必須使用abstract修飾约急,有抽象方法的類(lèi)一定是抽象類(lèi)。
規(guī)則:
- 抽象方法不能有方法體
- 抽象類(lèi)不能夠被實(shí)例化
- 抽象類(lèi)的構(gòu)造函數(shù)不能夠用來(lái)創(chuàng)造實(shí)例牵辣,主要用于被子類(lèi)調(diào)用
- 含有抽象方法的類(lèi)(包括直接定義了一個(gè)抽象方法奴饮;繼承了一個(gè)抽象父類(lèi)戴卜,但是沒(méi)有完全實(shí)例化父類(lèi)包含的抽象類(lèi);或是實(shí)現(xiàn)了一個(gè)接口师脂,但是沒(méi)有完全實(shí)例化接口包含的抽象方法)
public class Triangle extends Shape{
//定義三角形的三邊
private double a;
private double b;
private double c;
public Triangle(String color,double a,double b,double c)
{
super(color);
this.sideSides(a,b,c);
}
public void sideSides(double a,double b,double c)
{
if(a+b<=c||a+c<=b||c+b<=a)
{
System.out.print("兩邊之和必須大于第三邊");
return ;
}
this.a=a;
this.b=b;
this.c=c;
}
//重寫(xiě)計(jì)算周長(zhǎng)的方法
public double calPerimeter()
{
return a+b+c;
}
public String getType()
{
return "三角形";
}
public static void main (String[] args)
{
//如果不用抽象類(lèi)的話吃警,s1是不能夠直接調(diào)用gettype方法的啄育。
Shape s1=new Triangle("yello", 3, 4,5);
System.out.println(s1.getType());
System.out.print(s1.calPerimeter());
}
}
abstract與final不能同時(shí)出現(xiàn):abstract類(lèi)表示只能被繼承灸撰,但是final類(lèi)不能被繼承。
abstract和static一般不能同時(shí)修飾方法:static修飾的方法表示屬于類(lèi)的完疫,可以通過(guò)類(lèi)來(lái)訪問(wèn)债蓝。但是如果同時(shí)也是abstract的話,則沒(méi)有方法體芳誓。這就沒(méi)辦法調(diào)用锹淌。(內(nèi)部類(lèi)除外)
abstract和private不能同時(shí)修飾方法:private修飾的方法是不會(huì)被繼承的赠制。但是abstract需要繼承。
6.5.2 抽象類(lèi)的作用
作為子類(lèi)的模版烟号。
6.6 java8改進(jìn)的接口
將抽象類(lèi)“抽象”到極致汪拥,只包含抽象方法篙耗。就是接口。
6.6.1 接口的概念
接口定義的是多個(gè)類(lèi)共同的公共行為規(guī)范铣焊,接口里通常是定義一組公共方法曲伊。
接口不提供任何實(shí)現(xiàn)追他,體現(xiàn)的是實(shí)現(xiàn)和規(guī)范相分離的設(shè)計(jì)哲學(xué)邑狸。
6.6.2 java8中接口的定義
關(guān)鍵詞:interface
修飾符:public 或者省略,省略是默認(rèn)default
一個(gè)接口可以繼承多個(gè)接口
由于接口定義的是一種規(guī)范赚哗,因此接口沒(méi)有構(gòu)造器和初始化塊,接口可以包含成員變量(靜態(tài)常量)贿讹,靜態(tài)方法和抽象方法以及默認(rèn)方法够掠。都必須是public
- 靜態(tài)常量:無(wú)論是否有修飾符疯潭,都是public static final的,需要在定義的時(shí)候指定默認(rèn)值哭廉∑诜幔可以跨包訪問(wèn)钝荡,但是因?yàn)槭莊inal,不能修改值赎离。
- 接口里面的普通方法只能是public的抽象abstract方法
- 在接口定義默認(rèn)方法梁剔,需要使用default修飾(默認(rèn)都是public修飾舞蔽,不能static修飾)
- 在接口定義類(lèi)方法渗柿,需要使用static(默認(rèn)都是public ,不能用default修飾)
- java里面最多定義一個(gè)public的接口颊亮,如果有public的接口陨溅,則主文件名和接口名相同
6.6.3 接口的繼承
支持多繼承门扇,以逗號(hào)分格
6.6.4 使用接口
implements實(shí)現(xiàn)多個(gè)接口偿渡。如果一個(gè)類(lèi)繼承了一個(gè)接口卸察,就必須把里面的抽象方法都實(shí)現(xiàn)铅祸,否則就必須定義成抽象類(lèi)临梗。
實(shí)現(xiàn)接口的方法時(shí)必須使用public
模擬多繼承:接口名 引用變量名=new 類(lèi)(初始化參數(shù))稼跳,類(lèi)就可以訪問(wèn)接口的方法以及自己的方法汤善。類(lèi)的方法就變的很多。
package demo6;
//定義一個(gè)product接口
interface Product
{
int getProductTime();
}
public class Printer implements Product , Output{
private String[] printData=new String[MAX_CACHE_LINE];
//記錄當(dāng)前需打印的作業(yè)數(shù)
private int dataNum=0;
public void out()
{
//只要還有作業(yè)就繼續(xù)打印
while(dataNum>0)
{
System.out.println(printData[0]);
System.arraycopy(printData, 1, printData, 0, --dataNum);
}
}
public void getData(String msg)
{
if(dataNum>=MAX_CACHE_LINE)
{
System.out.println("輸出隊(duì)列已經(jīng)滿了不狮。添加失敗");
}else {
printData[dataNum++]=msg;
}
}
public int getProductTime()
{
return 45;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
//創(chuàng)建一個(gè)printer對(duì)象摇零,當(dāng)成output使用
Output o=new Printer();
o.getData("瘋狂jav");
o.getData("瘋狂jaba講義");
o.out();
o.getData("瘋狂安卓講義");
o.getData("瘋狂安卓");
o.out();
}
}
6.6.5 接口和抽象類(lèi)
接口:體現(xiàn)一種規(guī)范桶蝎,對(duì)于接口的實(shí)現(xiàn)者登渣,接口定義了必須實(shí)現(xiàn)那些服務(wù);對(duì)于接口的調(diào)用者粘优,規(guī)定了調(diào)用者可以調(diào)用哪些方法敬飒。
抽象類(lèi):體現(xiàn)一種模版的設(shè)計(jì)芬位,他是沒(méi)有設(shè)計(jì)完的一個(gè)類(lèi)无拗,需要子類(lèi)補(bǔ)充將它完成。
6.6.6 面向接口編程
- 簡(jiǎn)單的工廠模式
不太懂啊
package demo6;
public class Computer {
private Output out;
public Computer(Output out)
{
this.out=out;
}
//定義一個(gè)模擬獲得字符串的方法
public void keyIn(String msg)
{
out.getData(msg);
}
public void print()
{
out.out();
}
}
package demo6;
public class OutputFactory {
public Output getOutput()
{
return new Printer();
}
public static void main(String[] args) {
// TODO Auto-generated method stub
OutputFactory oF=new OutputFactory();
Computer c=new Computer(oF.getOutput());
c.keyIn("java");
c.keyIn("ilovayou");
c.print();
}
}
2.命令模式
定義一個(gè)接口昧碉,接口里面定義一個(gè)抽象的方法英染,作用在一個(gè)數(shù)組上揽惹。然后實(shí)例化這個(gè)接口,可以實(shí)例化多個(gè)四康,每個(gè)都是作用在數(shù)組上的一種方法搪搏,
闪金?疯溺??哎垦?囱嫩??漏设?墨闲??郑口?鸳碧?
6.7 內(nèi)部類(lèi)
定義在其他類(lèi)內(nèi)部的類(lèi)叫做內(nèi)部類(lèi)。
包含內(nèi)部類(lèi)的類(lèi)叫做外部類(lèi)犬性。
內(nèi)部類(lèi)的作用:
- 提供了更好的封裝性瞻离,不允許同一個(gè)包中的其他類(lèi)訪問(wèn)。
- 內(nèi)部類(lèi)可以直接訪問(wèn)外部類(lèi)的私有數(shù)據(jù)仔夺。因?yàn)閮?nèi)部類(lèi)可以當(dāng)作外部類(lèi)成員琐脏。外部類(lèi)不可以訪問(wèn)內(nèi)部類(lèi)的實(shí)現(xiàn)細(xì)節(jié)
- 匿名內(nèi)部類(lèi)適合用于創(chuàng)建只需要一次使用的類(lèi)。
內(nèi)部類(lèi)外部類(lèi)區(qū)別: - 內(nèi)部類(lèi)比外部類(lèi)多3個(gè)修飾符缸兔,private protected static
- 非靜態(tài)內(nèi)部類(lèi)不能有靜態(tài)成員
6.7.1 非靜態(tài)內(nèi)部類(lèi)
在外部類(lèi)里面使用非靜態(tài)內(nèi)部類(lèi)時(shí)日裙,和使用普通的類(lèi)沒(méi)有什么區(qū)別。非靜態(tài)內(nèi)部類(lèi)可以訪問(wèn)外部類(lèi)的pirvate成員惰蜜,因?yàn)榉庆o態(tài)內(nèi)部類(lèi)的對(duì)象里面昂拂,保存了一個(gè)外部類(lèi)對(duì)象的引用。
外部類(lèi)成員變量抛猖,內(nèi)部類(lèi)成員變量格侯,內(nèi)部類(lèi)里面方法的局部變量可以同名,用this區(qū)分财著。
外部類(lèi)不能夠訪問(wèn)非晶態(tài)內(nèi)部類(lèi)的成員联四,必須創(chuàng)建一個(gè)對(duì)象才行。new inner()撑教,朝墩,,因?yàn)橥獠款?lèi)存在的時(shí)候伟姐,內(nèi)部類(lèi)不一定存在收苏,但是內(nèi)部類(lèi)存在亿卤,外部類(lèi)一定存在。
不允許在外部類(lèi)的靜態(tài)成員中直接使用非靜態(tài)內(nèi)部類(lèi)
不允許在非靜態(tài)內(nèi)部類(lèi)里面定義靜態(tài)成員鹿霸。
6.7.2 靜態(tài)內(nèi)部類(lèi)
用static修飾的內(nèi)部類(lèi)叫做靜態(tài)內(nèi)部類(lèi)排吴。這個(gè)內(nèi)部類(lèi)屬于外部類(lèi)本身,不屬于外部類(lèi)的任何一個(gè)對(duì)象懦鼠。
外部類(lèi)不能夠用statc修飾钻哩,因?yàn)橥獠款?lèi)的上一級(jí)是包,所以沒(méi)有類(lèi)的概念葛闷,但是內(nèi)部類(lèi)的上一層是外部類(lèi)憋槐,所以可以用static修飾。
靜態(tài)內(nèi)部類(lèi)可以有靜態(tài)成員和非靜態(tài)成員淑趾,靜態(tài)內(nèi)部類(lèi)不能夠訪問(wèn)外部類(lèi)的實(shí)例成員,只能訪問(wèn)類(lèi)成員忧陪。(因?yàn)殪o態(tài)內(nèi)部類(lèi)里面只有外部類(lèi)的引用扣泊,沒(méi)有外部類(lèi)對(duì)象的引用)
外部類(lèi)依舊不能訪問(wèn)內(nèi)部類(lèi)的成員,但是可以通過(guò)類(lèi)名或者對(duì)象訪問(wèn)內(nèi)部類(lèi)成員對(duì)象嘶摊。
java允許定義接口內(nèi)部類(lèi)延蟹,默認(rèn)是public static修飾。也就是說(shuō)叶堆,接口的內(nèi)部類(lèi)一定是靜態(tài)內(nèi)部類(lèi)阱飘。
6.7.3 使用內(nèi)部類(lèi)
在外部類(lèi)內(nèi)部使用內(nèi)部類(lèi)
基本上與平常使用普通類(lèi)沒(méi)有區(qū)別。唯一的區(qū)別是不要在外部類(lèi)的靜態(tài)成員中使用非靜態(tài)內(nèi)部類(lèi)虱颗。
在外部類(lèi)以外使用非靜態(tài)內(nèi)部類(lèi)
在外部類(lèi)以外的地方定義內(nèi)部類(lèi)變量的語(yǔ)法:
outclassname.innerclassname name;
創(chuàng)建非靜態(tài)內(nèi)部類(lèi)對(duì)象(非靜態(tài)內(nèi)部類(lèi)的構(gòu)造器必須用外部類(lèi)對(duì)象調(diào)用)
outerInstance.new InnerConstructor()
class Out
{
class In
{
public In(String msg)
{
System.out.println(msg);
}
}
}
public class CreateInnerInstance {
public static void main(String[] args) {
// TODO Auto-generated method stub
//使用outclass.innerclass的形式定義內(nèi)部類(lèi)變量
Out.In in;
//創(chuàng)建外部類(lèi)對(duì)象
Out out=new Out();
//通過(guò)外部類(lèi)對(duì)象創(chuàng)建內(nèi)部類(lèi)對(duì)象
in=out.new In("測(cè)試出錯(cuò)");
}
}
1.創(chuàng)建非靜態(tài)內(nèi)部類(lèi)的子類(lèi)
package demo6;
public class SubClass extends Out.In {
public SubClass(Out out)
{
out.super("hello");
}
}
- 在外部類(lèi)以外使用靜態(tài)內(nèi)部類(lèi)
new outclass.innerConstruction
可以看出無(wú)論是靜態(tài)內(nèi)部類(lèi)還是非靜態(tài)內(nèi)部類(lèi)沥匈,聲明變量的方法都是一樣的。區(qū)別在于創(chuàng)建內(nèi)部類(lèi)對(duì)象忘渔。優(yōu)先考慮靜態(tài)內(nèi)部類(lèi)高帖。
6.7.4 局部?jī)?nèi)部類(lèi)
放在方法里面的內(nèi)部類(lèi)
一般不用
6.7.5 java8改進(jìn)的匿名內(nèi)部類(lèi)
匿名內(nèi)部類(lèi)適合創(chuàng)建只需要一次使用的類(lèi)。創(chuàng)建匿名內(nèi)部類(lèi)時(shí)會(huì)立即創(chuàng)建一個(gè)該類(lèi)的實(shí)例畦粮,這個(gè)類(lèi)定義立即消失散址,匿名內(nèi)部類(lèi)不能重復(fù)使用。
匿名內(nèi)部類(lèi)必須繼承一個(gè)父類(lèi)宣赔,或者實(shí)現(xiàn)一個(gè)接口预麸,但是最多只能是一個(gè)。
匿名內(nèi)部類(lèi)的兩條規(guī)則:
- 不能是抽象類(lèi)儒将,因?yàn)槌橄箢?lèi)不能被實(shí)例化吏祸,但是匿名內(nèi)部類(lèi)創(chuàng)建的時(shí)候就要?jiǎng)?chuàng)建對(duì)象
- 不能定義構(gòu)造器,因?yàn)槟涿麅?nèi)部類(lèi)沒(méi)有類(lèi)名椅棺。
最常用的創(chuàng)建匿名內(nèi)部類(lèi)是需要?jiǎng)?chuàng)建某個(gè)接口類(lèi)型的對(duì)象犁罩。
局部變量被匿名內(nèi)部類(lèi)訪問(wèn)齐蔽,局部變量相當(dāng)于自動(dòng)加了final修飾。因此不能夠再被修改床估。
6.8 java8新增的lambda表達(dá)式
6.8.1 lambda表達(dá)式入門(mén)
lambda表達(dá)式支持代碼作為方法參數(shù)含滴,可以創(chuàng)建只有一個(gè)抽象方法的接口的實(shí)例。
lambda表達(dá)式由形參列表 ->和方法體組成
6.8.2 lambda表達(dá)式和函數(shù)式接口
lambda表達(dá)式的目標(biāo)類(lèi)型必須是函數(shù)式接口
函數(shù)式接口代表只包含一個(gè)抽象方法的接口丐巫。函數(shù)式接口可以包含多個(gè)默認(rèn)方法谈况,類(lèi)方法,但只能有一個(gè)抽象方法递胧。
java8為函數(shù)式接口加了@FunctionalInterface注解 用于告訴編譯器更嚴(yán)格的檢查
6.8.3 方法引用和構(gòu)造器引用
如果代碼塊只有一行代碼碑韵,則可以在lambda表達(dá)式中使用方法引用和構(gòu)造引用。
引用類(lèi)方法 類(lèi)名::類(lèi)方法
引用特定對(duì)象的實(shí)力方法 特定對(duì)象::實(shí)例方法
引用某類(lèi)對(duì)象的實(shí)例方法 類(lèi)名::實(shí)例方法
引用構(gòu)造器 類(lèi)名::new
6.8.4 lambda表達(dá)式和匿名內(nèi)部類(lèi)的聯(lián)系和區(qū)別
lambda表達(dá)式是匿名內(nèi)部類(lèi)的一種簡(jiǎn)化缎脾。
相同點(diǎn):
都可以直接訪問(wèn)“effectively final”的局部變量祝闻,以及外部類(lèi)的成員變量
所創(chuàng)建的對(duì)象可以直接調(diào)用從接口中繼承的默認(rèn)方法
區(qū)別
匿名內(nèi)部類(lèi)可以為任意接口創(chuàng)建實(shí)例,而lambda表達(dá)式必須是函數(shù)式接口
匿名內(nèi)部類(lèi)可以為抽象類(lèi)甚至普通類(lèi)創(chuàng)建實(shí)例遗菠。
匿名內(nèi)部類(lèi)的方法體可以調(diào)用接口中定義的默認(rèn)方法联喘,但是lambda不可以,它只有對(duì)象可以調(diào)用辙纬。
6.9 枚舉類(lèi)
枚舉類(lèi)是指實(shí)例有限而且固定的類(lèi)
6.9.2 枚舉類(lèi)入門(mén)
枚舉類(lèi)是一種特殊的類(lèi)豁遭,可以有自己的成員變量,方法贺拣,可以實(shí)現(xiàn)一個(gè)或者多個(gè)接口蓖谢。
- 默認(rèn)繼承java.lang.Enum類(lèi),不能顯式繼承其他父類(lèi)譬涡。
- 使用Enum定義闪幽,非抽象的枚舉類(lèi)默認(rèn)是final修飾,不能派生子類(lèi)
- 構(gòu)造器為private
- 所有實(shí)例必須在第一行顯式列出昂儒,系統(tǒng)默認(rèn)加上public static final
- 如果需要使用某個(gè)實(shí)例沟使,用EnumClass.variable
6.9.3 枚舉類(lèi)的成員變量,方法和構(gòu)造器
枚舉類(lèi)的成員變量最好都使用private final修飾
如果構(gòu)造函數(shù)有參數(shù)渊跋,則在第一行列出實(shí)例的時(shí)候腊嗡,要寫(xiě)上參數(shù)。
枚舉類(lèi)的實(shí)例只能是枚舉值拾酝,不能隨意通過(guò)new來(lái)創(chuàng)建燕少。?蒿囤?客们?
6.9.4 實(shí)現(xiàn)接口的枚舉類(lèi)
與普通類(lèi)完全一樣,也需要實(shí)現(xiàn)該接口所包含的方法
如果不同的枚舉值想在調(diào)用一個(gè)方法時(shí)呈現(xiàn)不同的行為方式,則可以讓每個(gè)枚舉值分別實(shí)現(xiàn)該方法底挫,這個(gè)時(shí)候恒傻,不是在創(chuàng)建枚舉類(lèi)的實(shí)例,而是創(chuàng)建匿名子類(lèi)的實(shí)例建邓。
6.9.5 包含抽象方法的枚舉類(lèi)
每個(gè)枚舉值都必須為抽象方法提供實(shí)現(xiàn)盈厘,否則報(bào)錯(cuò)。
6.10 對(duì)象和垃圾回收
6.10.1 對(duì)象在內(nèi)存中的狀態(tài)
可達(dá)狀態(tài)
可恢復(fù)狀態(tài)
不可達(dá)狀態(tài)
6.10.2 強(qiáng)制垃圾回收
System.gc()
Runtime.getRuntime().gc()