W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
[TOC]
| 基本數(shù)據(jù)類(lèi)型 | 包裝類(lèi) |
| :-------- | --------: |
| byte | Byte |
| short | Short |
| int | Integer |
| char | Character |
| float | Float |
| double | Double |
| long | Long |
| boolean | Boolean |
除了Integer和Character定義的名稱(chēng)和對(duì)應(yīng)的基本類(lèi)型差異大,其他六種都是將首字母大寫(xiě)
<br> 把基本數(shù)據(jù)類(lèi)型 → 包裝類(lèi):通過(guò)對(duì)應(yīng)包裝類(lèi)的構(gòu)造方法實(shí)現(xiàn) <br> 除了Character外,其他包裝類(lèi)都可以傳入一個(gè)字符串參數(shù)構(gòu)建包裝類(lèi)對(duì)象 <br> 包裝類(lèi) → 基本數(shù)據(jù)類(lèi)型,包裝類(lèi)的實(shí)例方法xxxValue(); // xxx表示包裝類(lèi)對(duì)應(yīng)的基本數(shù)據(jù)類(lèi)型 <br> 代碼: <br> boolean bool = false; <br> Boolean b2 = new Boolean(bool); <br> Integer i = new Integer(3); <br> int i2 = i.intValue(); <br> Boolean b1 = new Boolean("TRue"); //true <br> boolean b2 = b1.booleanValue(); <br> Float f = new Float("3.14"); //3.14 <br> Integer i2 = new Integer("123s"); //NumberFormatException <br> ``` <br> **基本類(lèi)型和String之間的轉(zhuǎn)換** <br> String → 基本類(lèi)型,除了Character外所有的包裝類(lèi)提供parseXxx(String s)靜態(tài)方法, <br> 用于把一個(gè)特定的字符串轉(zhuǎn)換成基本類(lèi)型變量; <br> 基本類(lèi)型 → String,String 類(lèi)有靜態(tài)方法valueOf(),用于將基本類(lèi)型的變量轉(zhuǎn)換成String類(lèi)型 <br> 代碼: <br> ``` <br> String str = "66; <br> int i = Integer.parseInt(str); //String --& 基本類(lèi)型 <br> String s1 = String.valueOf(i); //基本類(lèi)型 --& String <br> ```
什么是自動(dòng)裝箱?:可把一個(gè)基本類(lèi)型變量直接賦給對(duì)應(yīng)的包裝類(lèi)對(duì)象或則Object對(duì)象
什么是自動(dòng)拆箱?:允許把包裝類(lèi)對(duì)象直接賦給對(duì)應(yīng)的基本數(shù)據(jù)類(lèi)型
代碼:
Integer i = 3; //裝箱
int i1 = i; //拆箱
Object flag = new Boolean(false);
if(flag instanceof Boolean){
Boolean b = (Boolean)flag;
boolean b2 = b;
}
什么是Object類(lèi)?
所有類(lèi)的公共父類(lèi),一旦一個(gè)類(lèi)沒(méi)有顯示地繼承一個(gè)類(lèi)則其直接父類(lèi)一定是Object
一切數(shù)據(jù)類(lèi)型都可用Object接收,class A extends Object{}等價(jià)于class A {}
代碼:常見(jiàn)方法
public boolean equals(Object obj):對(duì)象比較
public int hashCode():取得該對(duì)象的Hash碼
public String toString():對(duì)象描述
Object類(lèi)的 toString()方法:“對(duì)象的描述”
筆者建議所有類(lèi)都覆寫(xiě)此方法,直接打印輸出對(duì)象時(shí),會(huì)調(diào)用該對(duì)象的toString()方法
打印對(duì)象的時(shí)候,實(shí)際調(diào)用的對(duì)象實(shí)際指向的類(lèi)的自我描述:
全限定類(lèi)名+@+十六進(jìn)制的hashCode值,等價(jià)于 全限定類(lèi)名+@+IntegertoHexString(該對(duì)象.hashCode);
equals也是判斷是否指向同一個(gè)對(duì)象,沒(méi)有實(shí)際意義,有必要可以重寫(xiě)
public boolean equals(Object obj) {}
String 覆寫(xiě)了 Object的equals方法:只比較字符的序列是否相同
==用于判斷兩個(gè)變量是否相等
基本類(lèi)型:
引用類(lèi)型:必須指向同一個(gè)對(duì)象,才true
只能比較有父子或平級(jí)關(guān)系的兩個(gè)對(duì)象
new String("1") == new String("1"); ?
什么是代碼塊?
代碼塊指的是使用"{}"括起來(lái)的一段代碼,根據(jù)代碼塊存在的位置可以分為4種:
(1)普通代碼塊; (2)構(gòu)造代碼塊; (3)靜態(tài)代碼塊; (4)線程同步代碼塊;
代碼塊里變量的作用域:只在自己所在區(qū)域(前后的{})內(nèi)有效;
(1)普通代碼塊:普通代碼塊就是直接定義在方法或語(yǔ)句中定義的代碼塊
代碼:
.....main.....{
{
int x = 1;
System.out.println("普通代碼塊" + x);
}
int x = 99;
System.out.println("代碼塊之外" + x);
}
(2)構(gòu)造代碼塊:直接寫(xiě)在類(lèi)中的代碼塊,優(yōu)先于構(gòu)造方法執(zhí)行,每次實(shí)例化對(duì)象之前都會(huì)執(zhí)行構(gòu)造代碼塊
代碼:
public class Demo1 {
System.out.println("我是構(gòu)造代碼塊");
}
public Demo2(){
System.out.println("我是構(gòu)造方法");
}
public static void main(String[] args) {
Demo1 d1 = new Demo1();
Demo2 d2 = new Demo2();
}
}
(3)靜態(tài)代碼塊:使用static 修飾的構(gòu)造代碼塊:優(yōu)先于主方法執(zhí)行,優(yōu)先于構(gòu)造代碼塊執(zhí)行,不管有創(chuàng)建多少對(duì)象,靜態(tài)代碼塊只執(zhí)行一次,可用于給靜態(tài)變量賦值;
代碼:
public class Demo3 {
System.out.println("我是構(gòu)造代碼塊");
}
public Demo()4{
System.out.println("我是構(gòu)造方法");
}
static {
System.out.println("我是靜態(tài)代碼塊");
}
public static void main(String[] args) {
System.out.println("Main");
new Demo3();
new Demo4();
}
}
(4)線程同步代碼塊:在后面文章中筆者將詳細(xì)提到這個(gè)問(wèn)題!
有的時(shí)候我們?yōu)榱吮苊馔饨鐒?chuàng)建某類(lèi)的實(shí)例,就將某類(lèi)的構(gòu)造方法私有化,將它的構(gòu)造方法用private修飾:
私有化后外界就再也不能創(chuàng)建實(shí)例了,那內(nèi)部呢?
其實(shí)即使將某類(lèi)的構(gòu)造方法私有化起來(lái),外界也是可以創(chuàng)建它的實(shí)例的,此時(shí)就需要用到反射技術(shù)
代碼:
class A{
private A(){}
public void show(){
System.out.println("A");
}
}
public class Demo {
public static void main(String[] args) throws Exception{
Class<A& clz = A.class;
Constructor<A& c = clz.getDeclaredConstructor();
c.setAccessible(true);
A a = c.newInstance();
a.show();
}
}
什么是抽象類(lèi)?
(1).使用abstract關(guān)鍵字聲明的類(lèi)為抽象類(lèi)
(2).很多具有相同特征和行為的對(duì)象可以抽象為一個(gè)類(lèi),很多具有相同特征和行為的類(lèi)可以為一個(gè)抽象類(lèi)
(3).抽象類(lèi)規(guī)則:
1.抽象類(lèi)可以沒(méi)有抽象方法,有抽象方法的類(lèi)必須是抽象類(lèi)
2.非抽象類(lèi)繼承抽象類(lèi)必須實(shí)現(xiàn)所有有抽象方法
3.抽象類(lèi)可以有方法實(shí)現(xiàn)和屬性
4.抽象類(lèi)不能被實(shí)例化
5.抽象類(lèi)不能聲明為final
6.抽象類(lèi)可以有普通方法
抽象類(lèi)的語(yǔ)法格式:
//聲明一個(gè)抽象類(lèi)
public abstract class Wonmen{
private String name;
public abstract void say();//抽象方法
}
JAVA語(yǔ)言中使用abstract class來(lái)定義抽象類(lèi)代碼如下:
/**
*定義一個(gè)抽象類(lèi)
**/
public abstract class Demo5{
private String name; //定義私有成員變量屬性
private String address; //定義私有成員變量屬性
private int number; //定義私有成員變量屬性
//定義構(gòu)造方法
public Demo5(String name, String address, int number){
this.name = name;
this.address = address;
this.number = number;
}
public double computePay(){
System.out.println("這是 computePay");
return 0.0;
}
public void mailCheck(){
System.out.println("這是 " + this.name+ " " + this.address);
}
//定義toString方法
public String toString(){
return name + " " + address + " " + number;
}
//取得getName方法
public String getName(){
return name;
}
//getAddress方法
public String getAddress(){
return address;
}
//取得getNumber方法
public int getNumber(){
return number;
}
//設(shè)置Address方法
public void setAddress(String newAddress){
address = newAddress;
}
}
該類(lèi)是抽象類(lèi),但是它仍然有3個(gè)成員變量,7個(gè)成員方法和1個(gè)構(gòu)造方法
抽象方法:abstract關(guān)鍵字同樣可以用來(lái)聲明抽象方法,抽象方法只包含一個(gè)方法名,而沒(méi)有方法體
抽象方法沒(méi)有定義,方法名后面直接跟一個(gè)分號(hào),而不是花括號(hào)
public abstract class Demo6{
private String name;
private String address;
private int number;
public abstract double computePay();
//其余代碼
}
聲明抽象方法會(huì)造成以下兩個(gè)結(jié)果:
● 如果一個(gè)類(lèi)包含抽象方法,那么該類(lèi)必須是抽象類(lèi)
● 任何子類(lèi)必須重寫(xiě)父類(lèi)的抽象方法,或者聲明自身為抽象類(lèi)
什么是JAVA接口?:
(1).接口是一組行為的規(guī)范,定義,沒(méi)有實(shí)現(xiàn)
使用接口,可以讓我們的程序更加利于變化
接口是面向?qū)ο缶幊腆w系中的思想精髓之一
面向?qū)ο笤O(shè)計(jì)法則:基本接口編程
在JAVA編程語(yǔ)言中是一個(gè)抽象類(lèi)型,是抽象方法的集合
接口通常以interface來(lái)聲明。一個(gè)類(lèi)通過(guò)繼承接口的方式,從而來(lái)繼承接口的抽象方法
接口并不是類(lèi),編寫(xiě)接口的方式和類(lèi)很相似,但是它們屬于不同的概念
類(lèi)描述對(duì)象的屬性和方法。接口則包含類(lèi)要實(shí)現(xiàn)的方法
接口無(wú)法被實(shí)例化,但是可以被實(shí)現(xiàn)
一個(gè)實(shí)現(xiàn)接口的類(lèi),必須實(shí)現(xiàn)接口內(nèi)所描述的所有方法,否則就必須聲明為抽象類(lèi)
(2).JAVA接口的定義格式:
代碼:
接口實(shí)現(xiàn):
interface 接口名稱(chēng){ }
class Girl implements Hit{
//抽象方法;
public void cry(){
//方法體
}
}
(3).JAVA接口的使用規(guī)則:
1.接口可以繼承多個(gè)接口
2.一個(gè)類(lèi)可以實(shí)現(xiàn)多個(gè)接口,實(shí)現(xiàn)多個(gè)接口用逗號(hào)隔開(kāi)
3.抽象類(lèi)實(shí)現(xiàn)接口可以不實(shí)現(xiàn)方法
4.接口中的所有方法的訪問(wèn)權(quán)限都是public
5.接口中定義的屬性都是常量
(4).JAVA接口與類(lèi)相似點(diǎn):
● 一個(gè)接口可以有多個(gè)方法
● 接口文件保存在 .java 結(jié)尾的文件中,文件名使用接口名
●接口的字節(jié)碼文件保存在 .class 結(jié)尾的文件中
(5).JAVA接口與類(lèi)的區(qū)別:
● 接口不能用于實(shí)例化對(duì)象
● 接口沒(méi)有構(gòu)造方法
● 接口中所有的方法必須是抽象方法
● 接口不能包含成員變量,除了 static 和 final 變量
● 接口不是被類(lèi)繼承了,而是要被類(lèi)實(shí)現(xiàn)
● 接口支持多重繼承
● 接口相應(yīng)的字節(jié)碼文件必須在與包名稱(chēng)相匹配的目錄結(jié)構(gòu)中
(6).JAVA接口特性
●接口中每一個(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)接口的類(lèi)來(lái)實(shí)現(xiàn)接口中的方法
(7).JAVA抽象類(lèi)和接口的區(qū)別
● 1. 抽象類(lèi)中的方法可以有方法體,就是能實(shí)現(xiàn)方法的具體功能,但是接口中的方法是不可行的
● 2. 抽象類(lèi)中的成員變量可以是各種類(lèi)型的,而接口中的成員變量只能是 public static final 類(lèi)型
● 3. 接口中不能含有靜態(tài)代碼塊以及靜態(tài)方法(用 static 修飾的方法),而抽象類(lèi)是可以有靜態(tài)代碼塊和靜態(tài)方法
● 4. 一個(gè)類(lèi)只能繼承一個(gè)抽象類(lèi),而一個(gè)類(lèi)卻可以實(shí)現(xiàn)多個(gè)接口
JAVA接口的實(shí)現(xiàn):
代碼:
public class MammalInt implements Animal{
public void eat(){
System.out.println("Mammal eats");
}
public void travel(){
System.out.println("Mammal travels");
}
public int noOfLegs(){
return 0;
}
public static void main(String args[]){
MammalInt m = new MammalInt();
m.eat();
m.travel();
}
}
## 9.接口與抽象類(lèi)
接口與抽象類(lèi)相同點(diǎn):
都位于繼承的頂端,用于被其他實(shí)現(xiàn)或繼承;
都不能實(shí)例化;
都包含抽象方法,其子類(lèi)都必須覆寫(xiě)這些抽象方法;
接口與抽象類(lèi)區(qū)別:
抽象類(lèi)為部分方法提供實(shí)現(xiàn),避免子類(lèi)重復(fù)實(shí)現(xiàn)這些方法,提供代碼重用性;接口只能包含抽象方法;
一個(gè)類(lèi)只能繼承一個(gè)直接父類(lèi)(可能是抽象類(lèi)),卻可以實(shí)現(xiàn)多個(gè)接口;(接口彌補(bǔ)了Java的單繼承)
二者的選用:
優(yōu)先選用接口,盡量少用抽象類(lèi),需要定義子類(lèi)的行為,又要為子類(lèi)提供共性功能時(shí)才選用抽象類(lèi);
| NO. | 比較 | 抽象類(lèi) | 接口 |
| :-------- | --------:| :------: | :------: |
| 1 | 關(guān)鍵字 | 使用abstract class 聲明 | 使用interface聲明 |
| 2 | 定義 | 包含抽象方法的類(lèi) | 抽象方法和全局常量的集合 |
| 3 | 組成 | 屬性、方法、構(gòu)造方法、抽象方法、常量 | 全局常量、抽象方法 |
| 4 | 權(quán)限 | 抽象方法的權(quán)限可以任意 | 只能是public權(quán)限 |
| 5 | 使用 | 通過(guò)extends關(guān)鍵字繼承抽象類(lèi) | 通過(guò)implements關(guān)鍵字實(shí)現(xiàn)接口 |
| 6 | 局限 | 抽象類(lèi)存在單繼承局限 | 沒(méi)有局限,一個(gè)子類(lèi)可以實(shí)現(xiàn)多個(gè)接口 |
| 7 | 順序 | 一個(gè)子類(lèi)只能先繼承抽象類(lèi)再實(shí)現(xiàn)多個(gè)接口
| 8 | 設(shè)計(jì)模式 | 模板設(shè)計(jì) | 工廠設(shè)計(jì)模式、代理設(shè)計(jì)模式 |
| 9 | 實(shí)際作用 | 只能做一個(gè)模板使用 | 作為標(biāo)準(zhǔn)、表現(xiàn)能力 |
| 10 | 使用 | 兩者沒(méi)有什么本質(zhì)上的區(qū)別,但是從實(shí)際上來(lái)看,如果 一個(gè)程序中抽象類(lèi)和接口都可以使用的話,則一定要優(yōu)先考慮接口,因?yàn)榻涌诳梢员苊鈫卫^承所帶來(lái)的局限
| 11 | 實(shí)例化 | 都是依靠對(duì)象多態(tài)性,通過(guò)子類(lèi)進(jìn)行對(duì)象實(shí)例化 |
什么是內(nèi)部類(lèi)?:
內(nèi)部類(lèi)就是在類(lèi)里面的類(lèi)就是內(nèi)部類(lèi),內(nèi)部類(lèi)就是一個(gè)在類(lèi)的內(nèi)部定義的類(lèi)
類(lèi)中有類(lèi):內(nèi)部類(lèi):嵌套類(lèi)或者是外部類(lèi):宿主類(lèi)
把內(nèi)部類(lèi)隱藏在外部類(lèi)之內(nèi),不許同包的其他類(lèi)訪問(wèn)該類(lèi)
內(nèi)部類(lèi)可以訪問(wèn)外部類(lèi)的私有數(shù)據(jù),外部類(lèi)不能訪問(wèn)內(nèi)部類(lèi)的實(shí)現(xiàn)細(xì)節(jié),比如字段;
觀察編譯后的字節(jié)碼文件
非靜態(tài)內(nèi)部類(lèi);靜態(tài)內(nèi)部類(lèi),局部?jī)?nèi)部類(lèi),匿名內(nèi)部類(lèi)適合于僅使用一次使用的類(lèi)
成員內(nèi)部類(lèi)格式:
//聲明一個(gè)類(lèi)
class Outer{
//聲明一個(gè)內(nèi)部類(lèi)
class Inner(){}
}
編譯上述代碼會(huì)產(chǎn)生兩個(gè)文件 Outer.class和Outer$Inner.class
為什么要使用內(nèi)部類(lèi)?內(nèi)部類(lèi)的作用?
1.內(nèi)部類(lèi)可以很好的實(shí)現(xiàn)隱藏
一般的非內(nèi)部類(lèi),是不允許有 private 與protected權(quán)限的,但內(nèi)部類(lèi)可以
2.內(nèi)部類(lèi)擁有外圍類(lèi)的所有元素的訪問(wèn)權(quán)限
3.可是實(shí)現(xiàn)多重繼承
4.可以避免修改接口而實(shí)現(xiàn)同一個(gè)類(lèi)中兩種同名方法的調(diào)用
JAVA中的內(nèi)部類(lèi)共分為四種:
靜態(tài)內(nèi)部類(lèi)static inner class (also called nested class)
成員內(nèi)部類(lèi)member inner class
局部?jī)?nèi)部類(lèi)local inner class
匿名內(nèi)部類(lèi)anonymous inner class
(1).JAVA非靜態(tài)內(nèi)部類(lèi)
若外部類(lèi)字段,內(nèi)部類(lèi)字段,內(nèi)部類(lèi)方法變量同名,則其訪問(wèn)方式分別是:
訪問(wèn)外部類(lèi)的字段:外部類(lèi)類(lèi)名.this.字段
訪問(wèn)內(nèi)部類(lèi)字段:this.字段
訪問(wèn)內(nèi)部類(lèi)方法的局部變量:字段
代碼:
//內(nèi)部類(lèi)訪問(wèn)字段方法
//聲明一個(gè)類(lèi)
public class Neibulei{
public static void main(String [] args){
new Snake().show();//調(diào)用內(nèi)部類(lèi)方法
}
}
//聲明一個(gè)類(lèi)
class Snake{
private String name = "外部類(lèi)屬性";//定義一個(gè)私有屬性
//聲明一個(gè)內(nèi)部類(lèi)
private class Node{
public String name = "內(nèi)部類(lèi)屬性";
//定義一個(gè)方法
public void add2Tall(){
String name = "局部變量";
System.out.println("把"+name+"添加到尾巴");
System.out.println("把"+this.name+"添加到尾巴");
System.out.println("把"+Snake.this.name+"添加到尾巴");
}
}
//定義方法
public void show(){
new Node().add2Tall();//開(kāi)辟內(nèi)部類(lèi)的方法
}
}
(2).外部類(lèi)以外訪問(wèn)非靜態(tài)內(nèi)部類(lèi):
內(nèi)部類(lèi)不能是private修飾,否則不能訪問(wèn),外部類(lèi)以外的地方定義內(nèi)部類(lèi)變量
非靜態(tài)內(nèi)部類(lèi)對(duì)象是存放在外部類(lèi)的對(duì)象里的,因此在創(chuàng)建非靜態(tài)內(nèi)部類(lèi)對(duì)象之前,必須先創(chuàng)建其外部類(lèi)的對(duì)象
代碼:
//在外部類(lèi)以外訪問(wèn)非靜態(tài)內(nèi)部類(lèi)
//聲明一個(gè)類(lèi)
public class FangwenNeibu{
public static void main(String [] args){
Outer out = new Outer();//實(shí)例化外部對(duì)象,創(chuàng)建外部對(duì)象
Outer.Inner in = out.new Inner();//根據(jù)外部類(lèi)對(duì)象創(chuàng)建內(nèi)部類(lèi)對(duì)象
in.show();//調(diào)用方法
}
}
//聲明一個(gè)外部類(lèi)
class Outer{
//聲明一個(gè)內(nèi)部類(lèi)
class Inner{
//定義一個(gè)方法
public void show(){
System.out.println("非靜態(tài)內(nèi)部方法");
}
}
}
(3).靜態(tài)內(nèi)部類(lèi):
使用static修飾內(nèi)部類(lèi),該內(nèi)部類(lèi)屬于其外部類(lèi),而不屬于外部類(lèi)的實(shí)例;
靜態(tài)內(nèi)部類(lèi)可包括靜態(tài)成員也可包括非靜態(tài)成員。根據(jù)靜態(tài)成員不能訪問(wèn)非靜態(tài)成員的規(guī)定,所以靜態(tài)內(nèi)部類(lèi)不能訪問(wèn)外部類(lèi)實(shí)例成員,只能訪問(wèn)外部類(lèi)的靜態(tài)成員;
代碼:
//靜態(tài)內(nèi)部類(lèi)
//聲明一個(gè)類(lèi)
public class JingTai{
public static void main(String [] args){
new Outer().test();//創(chuàng)建外部類(lèi)對(duì)象并調(diào)用方法test
}
}
//聲明一個(gè)外部類(lèi)
class Outer{
private String name = "will";//聲明一個(gè)私有屬性并賦值給name
private static int age = 17;//聲明一個(gè)私有靜態(tài)整形常量布置給age
//定義一個(gè)靜態(tài)內(nèi)部類(lèi)
static class StaticInner{
private String s = "ooxx";//定義一個(gè)私有的屬性并把值賦值給s變量
private static int num = 13;//定義一個(gè)私有的屬性并把值賦給整形num
//定義方法
public void show(){
//System.out.println(name);//不能訪問(wèn)
System.out.println(age);//可訪問(wèn)
System.out.println(new Outer().name);//開(kāi)辟外部類(lèi)并調(diào)用外部屬性
}
}
//定義方法
public void test(){
//System.out.println(s);//訪問(wèn)不到
//System.out.println(num);//訪問(wèn)不到
System.out.println(StaticInner.num);//可以訪問(wèn)
System.out.println(new StaticInner().s);//可以訪問(wèn)
new StaticInner().show();//創(chuàng)建內(nèi)部類(lèi)對(duì)象并調(diào)用內(nèi)部類(lèi)方法show
}
}
(4).外部以訪問(wèn)靜態(tài)類(lèi)內(nèi)部:
代碼:
//在外部以訪問(wèn)靜態(tài)類(lèi)內(nèi)部
//聲明一個(gè)類(lèi)
public class WaiFangNei{
public static void main(String [] args){
Outer.StaticInner.staticShow();//調(diào)用靜態(tài)內(nèi)部類(lèi)靜態(tài)方法
new Outer.StaticInner().show();//調(diào)用靜態(tài)內(nèi)部類(lèi)實(shí)例方法
}
}
//聲明一個(gè)外部類(lèi)
class Outer{
//聲明一個(gè)靜態(tài)內(nèi)部類(lèi)
static class StaticInner{
//定義一個(gè)show方法
public void show(){
System.out.println("靜態(tài)內(nèi)部類(lèi)實(shí)例方法");//輸出
}
//靜態(tài)方法
public static void staticShow(){
System.out.println("靜態(tài)內(nèi)部類(lèi)靜態(tài)方法");//輸出
}
}
}
(5).局部?jī)?nèi)部類(lèi):
局部?jī)?nèi)部類(lèi):定義在方法里的內(nèi)部類(lèi);
特點(diǎn):不能在宿主類(lèi)以外的地方使用,局部?jī)?nèi)部類(lèi)也不能使用訪問(wèn)修飾符和static修飾;
局部?jī)?nèi)部類(lèi)只能訪問(wèn)方法中final修飾的局部變量:因?yàn)閒inal修飾的變量相當(dāng)于一個(gè)常量,其生命周期超出了方法運(yùn)行的生命周期;
代碼:
//局部?jī)?nèi)類(lèi)
//聲明一個(gè)類(lèi)
public class JuBu{
String name = "will";//定義屬性
//定義主方法
public static void main(String [] args){
new JuBu().show();
}
}
//聲明一個(gè)方法
public void show(){
final int num = 10;//final修飾局部變量
//定義一個(gè)內(nèi)部類(lèi)
class localClass{
//定義方法
public void test(){
System.out.println(name+"--&"+num);
}
}
new localClass().test();//調(diào)用
}
(6).局部?jī)?nèi)部類(lèi):
局部?jī)?nèi)部類(lèi):定義在方法里的內(nèi)部類(lèi);
特點(diǎn):不能在宿主類(lèi)以外的地方使用,局部?jī)?nèi)部類(lèi)也不能使用訪問(wèn)修飾符和static修飾;
局部?jī)?nèi)部類(lèi)只能訪問(wèn)方法中final修飾的局部變量:因?yàn)閒inal修飾的變量相當(dāng)于一個(gè)常量,其生命周期超出了方法運(yùn)行的生命周期;
適合只使用一次的類(lèi),不能是抽象類(lèi),因?yàn)橄到y(tǒng)在創(chuàng)建匿名內(nèi)部類(lèi)的時(shí)候,會(huì)立即創(chuàng)建匿名內(nèi)部類(lèi)的對(duì)象
匿名內(nèi)部類(lèi)不能定義構(gòu)造器,因?yàn)槟涿麅?nèi)部類(lèi)沒(méi)有類(lèi)名
匿名內(nèi)部類(lèi)格式:
new 父類(lèi)構(gòu)造器([實(shí)參列表]) 或 接口(){
//匿名內(nèi)部類(lèi)的類(lèi)體部分
}
注意:匿名內(nèi)部類(lèi)必須繼承一個(gè)父類(lèi)或者實(shí)現(xiàn)一個(gè)接口,但最多只能一個(gè)父類(lèi)或?qū)崿F(xiàn)一個(gè)接口;
(7).枚舉類(lèi)(enum):
什么是枚舉?:
枚舉就是要讓各種類(lèi)型的變量的取值只能為若干個(gè)固定值得一個(gè)
枚舉就是要讓某個(gè)類(lèi)型的變量的取值只能為若干個(gè)固定值中的一個(gè),否則編譯器就會(huì)報(bào)錯(cuò)
枚舉可以讓編譯器在編譯時(shí)就控制源程序賦給的非法值,使用普通變量的方式在開(kāi)發(fā)階段無(wú)法實(shí)現(xiàn)這一目標(biāo)
在JDK1.5之后,使用關(guān)鍵字enum定義一種新的類(lèi)型,稱(chēng)為枚舉類(lèi)型
使用enum聲明,默認(rèn)直接繼承了java.lang.Enum類(lèi),而不是Object類(lèi);
枚舉類(lèi)的對(duì)象是固定的,實(shí)例個(gè)數(shù)有限,枚舉對(duì)象后可以跟()
枚舉元素必須位于枚舉類(lèi)體中的最開(kāi)始部分,枚舉元素后要有分號(hào)與其他成員分隔
枚舉類(lèi)的構(gòu)造方法的權(quán)限修飾符默認(rèn)是private
一旦枚舉對(duì)象后面加上{},那么該對(duì)象實(shí)際是枚舉匿名內(nèi)部類(lèi)對(duì)象;
所有枚舉類(lèi)都提供一個(gè)靜態(tài)的values()方法(返回該枚舉類(lèi)所有對(duì)象組成的數(shù)組),便于遍歷所有枚舉對(duì)象;
所有枚舉類(lèi)都提供一個(gè)靜態(tài)的valueOf(String name)方法, 返回枚舉類(lèi)中對(duì)象名等于 name的對(duì)象
Enum是一個(gè)抽象類(lèi),是所有枚舉類(lèi)的直接父類(lèi);
Enum常見(jiàn)方法:
String name(); // 返回枚舉實(shí)例名稱(chēng);
int ordinal(); // 返回枚舉實(shí)例在枚舉類(lèi)中的索引,從0開(kāi)始;
String toString(); // 返回枚舉對(duì)象的"自我描述";
在switch語(yǔ)句中使用枚舉對(duì)象;
在枚舉類(lèi)中使用toString方法;
使用for-each中操作枚舉對(duì)象;
枚舉類(lèi)的構(gòu)造方法;
枚舉類(lèi)覆寫(xiě)接口抽象方法的兩種方式;注意:匿名內(nèi)部類(lèi),枚舉實(shí)現(xiàn)單例模式;
代碼:
//枚舉類(lèi)
//聲明一個(gè)類(lèi)
public class Meiju{
//定義主方法
public static void main(String [] args){
RnumDemo rnON = RnumDemo.ON;
System.out.println(rnON);
}
}
//聲明一個(gè)枚舉類(lèi)
enum RnumDemo{
ON,OFF;
}
(8).枚舉類(lèi)的構(gòu)造方法:
enum Colors {
RED("紅"),GREEN("綠"),BLUE("藍(lán)");
private String name;
private Color(String name){
this.name = name;
}
public String getName(){
return name;
}
public String toString() {
return this.name;//this表示誰(shuí) ?
}
}
什么是異常?:
在程序中異常是阻止當(dāng)前方法或作用域繼續(xù)執(zhí)行的問(wèn)題,在程序中導(dǎo)致程序中斷運(yùn)行的一些指令
通俗的說(shuō),異常就是程序在運(yùn)行時(shí)出現(xiàn)的不正常情況;
編寫(xiě)的程序不可能一帆風(fēng)順,若異常產(chǎn)生,卻沒(méi)進(jìn)行正確的處理。則可能導(dǎo)致程序的中斷,造成損失,所以我們?cè)陂_(kāi)發(fā)中要考慮到各種異常的發(fā)生,并對(duì)其作出正確的處理,確保程序的正常執(zhí)行
JAVA異常體系:
Throwable
Error
通常指JVM出現(xiàn)重大問(wèn)題如:運(yùn)行的類(lèi)不存在或者內(nèi)存溢出
不需要編寫(xiě)針對(duì)代碼對(duì)其處理,程序無(wú)法處理
Exception
在運(yùn)行時(shí)運(yùn)行出現(xiàn)的一些情況,可以通過(guò)try,catch,finally處理
Exception 和 Error的子類(lèi)名大都是以父類(lèi)名作為后綴
JAVA異常其實(shí)是對(duì)不正常情況的一種描述,并將其封裝成對(duì)象
JAVA在 設(shè)計(jì)異常體系時(shí),將容易出現(xiàn)的異常情況都封裝成了對(duì)象
JAVA 內(nèi)置異常類(lèi)
JAVA語(yǔ)言定義了一些異常類(lèi)在 java.lang 標(biāo)準(zhǔn)包中
標(biāo)準(zhǔn)運(yùn)行時(shí)異常類(lèi)的子類(lèi)是最常見(jiàn)的異常類(lèi)。由于 java.lang 包是默認(rèn)加載到所有的 Java 程序的,所以大部分從運(yùn)行時(shí)異常類(lèi)繼承而來(lái)的異常都可以直接使用,Java 根據(jù)各個(gè)類(lèi)庫(kù)也定義了一些其他的異常,下面的表中列出了 Java 的非檢查性異常
| 異常 | 描述 |
| :-------- | --------:|
| ArithmeticException | 當(dāng)出現(xiàn)異常的運(yùn)算條件時(shí),拋出此異常。例如,一個(gè)整數(shù)"除以零"時(shí),拋出此類(lèi)的一個(gè)實(shí)例 |
| ArrayStoreException | 將錯(cuò)誤類(lèi)型的對(duì)象存儲(chǔ)到一個(gè)對(duì)象數(shù)組時(shí)拋出的異常 |
| ArrayIndexOutOfBoundsException | 用非法索引訪問(wèn)數(shù)組時(shí)拋出的異常。如果索引為負(fù)或大于等于數(shù)組大小,則該索引為非法索引 |
| ClassCastException | 將對(duì)象強(qiáng)制轉(zhuǎn)換為不是實(shí)例的子類(lèi)時(shí),拋出該異常 |
| IllegalMonitorStateException | 拋出的異常表明某一線程已經(jīng)試圖等待對(duì)象的監(jiān)視器,或者試圖通知其他正在等待對(duì)象的監(jiān)視器而本身沒(méi)有指定監(jiān)視器的線程 |
| IllegalArgumentException | 拋出的異常表明向方法傳遞了一個(gè)不合法或不正確的參數(shù) |
| IllegalStateException | 在非法或不適當(dāng)?shù)臅r(shí)間調(diào)用方法時(shí)產(chǎn)生的信號(hào),換句話說(shuō),即 Java 環(huán)境或 Java 應(yīng)用程序沒(méi)有處于請(qǐng)求操作所要求的適當(dāng)狀態(tài)下 |
| IllegalThreadStateException | 線程沒(méi)有處于請(qǐng)求操作所要求的適當(dāng)狀態(tài)時(shí)拋出的異常 |
| IndexOutOfBoundsException | 指示某排序索引(例如對(duì)數(shù)組、字符串或向量的排序)超出范圍時(shí)拋出 |
| NegativeArraySizeException | 應(yīng)用程序創(chuàng)建大小為負(fù)的數(shù)組,則拋出該異常 |
| NullPointerException | 應(yīng)用程序在需要對(duì)象的地方使用 null 時(shí),拋出該異常 |
| NumberFormatException | 應(yīng)用程序試圖將字符串轉(zhuǎn)換成一種數(shù)值類(lèi)型,但該字符串不能轉(zhuǎn)換為適當(dāng)格式時(shí),拋出該異常 |
| SecurityException | 由安全管理器拋出的異常,指示存在安全侵犯 |
| StringIndexOutOfBoundsException | 異常由 String 方法拋出,指示索引或者為負(fù),或者超出字符串的大小 |
| UnsupportedOperationException | 不支持請(qǐng)求的操作時(shí),拋出該異常 |
| ClassNotFoundException | 應(yīng)用程序試圖加載類(lèi)時(shí),找不到相應(yīng)的類(lèi),拋出該異常 |
| CloneNotSupportedException | 當(dāng)調(diào)用Object類(lèi)中的 clone 方法克隆對(duì)象,但該對(duì)象的類(lèi)無(wú)法實(shí)現(xiàn) Cloneable 接口時(shí),拋出該異常 |
| IllegalAccessException | 拒絕訪問(wèn)一個(gè)類(lèi)的時(shí),拋出該異常 |
| InstantiationException | 使用 Class 類(lèi)中的 newInstance 方法創(chuàng)建一個(gè)類(lèi)的實(shí)例,而指定的類(lèi)對(duì)象因?yàn)槭且粋€(gè)接口或是一個(gè)抽象類(lèi)而無(wú)法實(shí)例化時(shí),拋出該異常 |
| InterruptedException | 一個(gè)線程被另一個(gè)線程中斷,拋出該異常 |
| NoSuchFieldException | 請(qǐng)求的變量不存在 |
| NoSuchMethodException | 請(qǐng)求的方法不存在 |
演示有異常程序的代碼
public class Demo7 {
public static void main(String[] args){
System.out.println("begin");
divide(17/0);
System.out.println("ending");
}
publc static void divide(int a,int b){
int c= a/b;
}
}
一旦出現(xiàn)異常,程序會(huì)立即終止
看完上面得異常程序,讀者思考,將如何處理異常程序呢?
異常處理過(guò)程分析:
一旦產(chǎn)生異常,則系統(tǒng)會(huì)自動(dòng)產(chǎn)生一個(gè)異常類(lèi)的實(shí)例化對(duì)象
此時(shí)如果存在于try語(yǔ)句,則會(huì)自動(dòng)找到匹配的catch語(yǔ)句執(zhí)行
如果沒(méi)有異常處理,則程序?qū)⑼顺觯⒂上到y(tǒng)報(bào)告錯(cuò)誤
所有的catch根據(jù)方法的參數(shù)匹配異常類(lèi)的實(shí)例化對(duì)象,如果匹配成功,則表示由此catch進(jìn)行處理
下面筆者將詳細(xì)介紹JAVA處理異常的5個(gè)關(guān)鍵字
JAVA異常處理的5個(gè)關(guān)鍵字
try 與 catch
finally
throw 與 throws
捕獲異常:先捕獲小異常再捕獲大異常
程序是調(diào)出來(lái)的,不是立馬編寫(xiě)出來(lái)的;多測(cè)試是程序員的必修課之一
JAVA異常處理格式:
try{
//可能出異常的代碼
} catch(異常類(lèi)型 對(duì)象){
//處理該異常類(lèi)型的語(yǔ)句
}
finally {
//異常的統(tǒng)一出口
//一定會(huì)執(zhí)行的代碼
//catch塊使用System.exit(1);除外
}
當(dāng)try語(yǔ)句塊出現(xiàn)異常,程序會(huì)自動(dòng)跳到catch語(yǔ)句塊去找匹配的異常類(lèi)型,并執(zhí)行異常處理語(yǔ)句,finally語(yǔ)句塊是異常的統(tǒng)一出口,異常處理后,程序不會(huì)因?yàn)槌霈F(xiàn)異常而退出
異常處理代碼:
//異常處理
//聲明一個(gè)類(lèi)
public class Yichang{
//方法
public static void main(String [] args){
int a = 10;//定義一個(gè)常量
int b = 0;//定義一個(gè)常量
int c = 0;
//把有可能發(fā)生異常的代碼塊段放到try塊中,通過(guò)catch語(yǔ)句進(jìn)行異常捕獲
try{
c = a/b;
}catch(ArithmeticException ex){
System.out.println("算數(shù)運(yùn)算異常");
}
System.out.println(c);
}
}
Throwable中的方法
String getMessage(); 獲取異常信息,返回字符串
String toString(); 獲取異常類(lèi)名和異常信息,返回字符串
void printStackTrace(); 打印異常在堆棧中的跟蹤信息;
獲取異常類(lèi)名和異常信息,以及異常出現(xiàn)在程序中的位置
方便程序開(kāi)發(fā)階段的調(diào)試(一般要打開(kāi)),JVM默認(rèn)的異常處理機(jī)制;
JAVA多異常處理:
聲明異常時(shí)盡可能聲明具體異常類(lèi)型,方便更好的處理;
方法聲明幾個(gè)異常就對(duì)應(yīng)有幾個(gè)catch塊;
若多個(gè)catch塊中的異常出現(xiàn)繼承關(guān)系,父類(lèi)異常catch塊放在最后;
在catch語(yǔ)句塊使用Exception類(lèi)作為異常類(lèi)型時(shí)
所有子類(lèi)實(shí)例都可以使用父類(lèi)接收(向上轉(zhuǎn)型),即所有的異常對(duì)象都可以使用Exception接收;
注:在java處理多異常時(shí)捕獲小范圍的異常必須放在大范圍異常之前
JAVA多異常處理格式:
try{
//可能出異常的代碼
} catch(異常類(lèi)A 對(duì)象){
//處理異常類(lèi)型A的語(yǔ)句
}catch(異常類(lèi)B 對(duì)象){
//處理異常類(lèi)型B的語(yǔ)句
}.....
finally {
//一定會(huì)執(zhí)行的代碼
//catch塊使用System.exit(1);除外
}
當(dāng)try語(yǔ)句塊出現(xiàn)異常,程序會(huì)自動(dòng)跳到catch語(yǔ)句塊去找匹配的異常類(lèi)型,并執(zhí)行異常處理語(yǔ)句,finally語(yǔ)句塊是異常的統(tǒng)一出口,異常處理后,程序不會(huì)因?yàn)槌霈F(xiàn)異常而退出
JAVA異常的分類(lèi):
(1).編譯時(shí)被檢查異常; ---& Checked異常,在程序中必須使用try...catch處理
Checked異常特點(diǎn):JAVA編譯器會(huì)檢查它,也就說(shuō)程序中一旦出現(xiàn)這類(lèi)異常,要么是沒(méi)有try-catch語(yǔ)句捕獲,或throws語(yǔ)句沒(méi)有聲明拋出它,編譯就不會(huì)通過(guò),也就說(shuō)這種異常,程序要求必須處理
(2).編譯時(shí)不被檢測(cè)的異常; ---& Runtime異常,可以不使用try...catch處理,但一旦出現(xiàn)異常就將由JVM處理
Runtime異常特點(diǎn):這種異常Java編譯器不會(huì)檢查它,也就說(shuō)程序中出現(xiàn)這類(lèi)異常的時(shí)候,即使不處理也沒(méi)有問(wèn)題,但是一旦出現(xiàn)異常,程序?qū)惓=K止,若采用異常處理,則會(huì)被相應(yīng)的程序執(zhí)行處理
throw關(guān)鍵字:
自行拋出一個(gè)異常對(duì)象,拋出異常類(lèi)的對(duì)象;若throw拋出的是Runtime異常:
程序可以顯示使用try...catch來(lái)捕獲并處理,也可以不管,直接交給方法調(diào)用者處理;若throw拋出Checked異常
要么放在try里自己處理,要么放在一個(gè)throws聲明的方法里面,交給調(diào)用者處理
throws 與 throw關(guān)鍵字
throws用于在方法上聲明該方法不需要處理的異常類(lèi)型
throw用于拋出具體異常類(lèi)的對(duì)象
throws與throw的區(qū)別:
thorws用在方法上,后面跟異常類(lèi)名,可以是多個(gè)異常類(lèi)
throw用在方法內(nèi),后面跟異常對(duì)象,只能是一個(gè)
聲明拋出一個(gè) RemoteException 異常代碼:
如果一個(gè)方法沒(méi)有捕獲一個(gè)檢查性異常,那么該方法必須使用 throws 關(guān)鍵字來(lái)聲明。throws 關(guān)鍵字放在方法簽名的尾部。
也可以使用 throw 關(guān)鍵字拋出一個(gè)異常,無(wú)論它是新實(shí)例化的還是剛捕獲到的。
import java.io.*;
public class className{
public void deposit(double amount) throws RemoteException{
throw new RemoteException();
}
}
一個(gè)方法可以聲明拋出多個(gè)異常,多個(gè)異常之間用逗號(hào)隔開(kāi)。
例如,下面的方法聲明拋出 RemoteException 和 InsufficientFundsException:
import java.io.*;
public class className{
public void withdraw(double amount) throws RemoteException,
InsufficientFundsException
{
}
finally關(guān)鍵字:
異常的統(tǒng)一出口:不管try塊程序是否異常,也不管哪個(gè)catch執(zhí)行,finally塊總會(huì)執(zhí)行
try語(yǔ)句塊或會(huì)執(zhí)行的catch語(yǔ)句塊使用了JVM系統(tǒng)退出語(yǔ)句例外;//System.exit(1);
try塊必須和 catch塊或和finally同在,不能單獨(dú)存在,二者必須出現(xiàn)一個(gè)
不要在finally中使用return 或throw語(yǔ)句,否則將會(huì)導(dǎo)致try、catch中的return或throw失效
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: