1.面向?qū)ο笈c面向過程的區(qū)別
面向過程:
優(yōu)點:比面向過程性能好,因為面向?qū)ο笳{(diào)用類的時候需要實例化,比較消耗資源,像單片機,嵌入式等等一般采用的是面向過程開發(fā),因為比較消耗資源
缺點:沒有面向?qū)ο笠子诰S護,擴展,復(fù)用
面向?qū)ο?
優(yōu)點:易于維護,易于復(fù)用,易于擴展,可以降低系統(tǒng)的耦合度,是系統(tǒng)更加的靈活
缺點:比較消耗資源,性能低于面向過程
2.java語言的特點
1.簡單易學(xué)
2.面向?qū)ο?繼承,分裝,多態(tài))
3.與平臺無關(guān)(運行在jvm當中)
4.安全性
5.可靠性
6.支持多線程( C++ 語言沒有內(nèi)置的多線程機制,因此必須調(diào)用操作系統(tǒng)的多線程功能來進行多線程程序設(shè)計,而 Java 語言卻提供了多線程支持);
7.支持網(wǎng)絡(luò)編程并且很方便( Java 語言誕生本身就是為簡化網(wǎng)絡(luò)編程設(shè)計的,因此 Java 語言不僅支持網(wǎng)絡(luò)編程而且很方便);
8.編譯與解釋并存
3.jdk,jre,jvm三者之間的區(qū)別與聯(lián)系
JDK:java開發(fā)工具包,包括jre與其他的一些供開發(fā)者使用的包。
JRE:java運行是環(huán)境,普通的用戶只需要安裝JRE來運行程序就可以了,程序員必須安裝JDK來調(diào)試,開發(fā),運行java程序。
jvm:java虛擬機,當我們運行一個程序的時候,jvm負責將字節(jié)碼文件(.class)轉(zhuǎn)換為特定的機器碼文件,jvm提供了內(nèi)存管理/垃圾回收/安全機制,jvm與硬件與操作系統(tǒng)無關(guān),這中與平臺無關(guān)的性能,正是java可以一次編譯處處運行的原因
區(qū)別與聯(lián)系:
JDK用于開發(fā),JRE用于運行java程序
jdk與JRE當中都含有JVM
JVM是java編程的核心,并且擁有平臺無關(guān)性
4.什么是字節(jié)碼,字節(jié)碼的最大好處是什么?
在java當中,供JVM理解的代碼(.class)叫做字節(jié)碼,他只面向JVM,不面向任何特點的處理器。
java程序生成.class文件,他只需要面向JVM即可,jvm當中的解釋器將.class代碼解釋為對應(yīng)機器的機器碼,JVM在任何平臺都提供給編譯程序一個相同的接口,每個個平臺的解釋器是不同的,但是都實現(xiàn)的JVM是相同的(對任何平臺的編譯程序都提供了相同的接口)。
JVM將字節(jié)碼代碼交給解釋器解釋,解釋器將代碼生成特定機器上的機器碼,然后在機器上運行。
字節(jié)碼的好處:
字節(jié)碼并不是針對某一特定的機器的,他只是針對JVM的,因此無需再重新編譯就可以在不同的計算機上面運行。
5.java與C++的區(qū)別
1.都是面向?qū)ο笳Z言
2.java不提供指針來訪問內(nèi)存,安全性更高
3.java當中是單繼承的,c++當中是多繼承的
4.java當中有自動內(nèi)存管理機制,無需程序員手動釋放內(nèi)存空間
6.java應(yīng)用程序與小程序的主類有什么不同
一個java應(yīng)用程序可以有很多個類,但是只能有一個主類,這個主類是包含main()方法的類,而在java小程序當?shù)闹黝愐欢ㄊ抢^承自系統(tǒng)類JApplet或者Applet的類,應(yīng)用程序的主類不一定是public,小程序的主類一定是public。
7.java應(yīng)用程序與小程序之間的區(qū)別
簡單來說,應(yīng)用程序是從主線程(main)啟動的,小程序沒有main方法,他是鑲嵌在瀏覽器(調(diào)用init()線程或者run()來啟動)當中運行的。嵌入瀏覽器這點與flash的小游戲類似。
8.字符串常量與字符常量的區(qū)別
在java當中每一種基本數(shù)據(jù)類型所占的字節(jié)大小是固定的,并不像其他大多數(shù)編程語言那樣隨著機器硬件架構(gòu)的變化而變化,這種鎖占存儲空間的固定正是java語言比吉他語言更具移植性的原因之一。

注意在進行自動轉(zhuǎn)換的時候;long可以直接轉(zhuǎn)換為float,雖然long是8個字節(jié),float是4個字節(jié),但是浮點數(shù)在內(nèi)存中的32位不是簡單地轉(zhuǎn)換為十進制,而是通過公式 V=(-1)^s * M * 2^E 來計算而來,通過這個公式雖然,只有4個字節(jié),但浮點數(shù)最大值要比長整型的范圍要大。
小數(shù)的默認數(shù)據(jù)類型是double,比如3.21,默認是double類型的,float a=3.21會報錯,整數(shù)的默認數(shù)據(jù)類型是int,比如3,默認是int類型的
當所占的字節(jié)大小是相同的時候,整數(shù)可以轉(zhuǎn)換為小數(shù),小數(shù)不能轉(zhuǎn)換為整數(shù)
============下面的是正確的==============
long a=3;
float t=a;
double f=a;
============下面的是錯誤的==============
double d=3.21;
long l=d;
即:long可以轉(zhuǎn)換為float,double,逆向則不可以
9. 構(gòu)造器 Constructor 是否可被 override
父類的私有屬性與構(gòu)造器并不能被繼承,所以Construct不能被重寫(override),但是可以被重載(overload)
10.重載與重寫的區(qū)別
重載(5不同):同一個類當中,方法名必須相同,參數(shù)類型可以不同,參數(shù)類型的順序可以不同,參數(shù)個數(shù)不同,方法返回值與權(quán)限修飾符可以不同
重寫(2同2小1大):有父子繼承關(guān)系的類當中,方法名,參數(shù)列表必須相同。返回值類型,拋出異常必須要小于等于父類。權(quán)限修飾符范圍大于等于父類,
如果父類方法訪問修飾符為 private 則子類當中就不能叫做重寫。
11.面向?qū)ο蟮娜筇匦?/h1>
封裝:將類的屬性私有化,提供一些可以供外界訪問的屬性set,get方法,如果不想被外界訪問,可以不提供set,get方法,但是這樣這個類就沒有意義了。
繼承:使用已經(jīng)存在的類作為基類建立新類的技術(shù),新類可以在基類的基礎(chǔ)上面進行拓展,通過繼承可以非常方便的復(fù)用以前的代碼
關(guān)于繼承:
子類擁有父類的一切非private修飾方法與屬性
子類可以在父類的基礎(chǔ)上面進行擴展,可以有自己的方法與屬性
多態(tài):子類的實例賦值給父類的引用
Parent p=new Child();
p.test();
引用變量所指向的具體類型(Parent/Child未知)與引用變量所調(diào)用的方法(Parent的test方法,還是Child的test方法未知),只有在運行的時候才知道,在運行時才可以確定
java當中有2中方法可以實現(xiàn)多態(tài):繼承父類(重寫父類當中的方法),實現(xiàn)接口(實現(xiàn)接口并重寫接口當中的某個方法)。
package com.xd.map;
public class Child extends Parent {
public void test() {
System.out.println("這是子類...");
}
public static void main(String[] args) {
Parent parent=new Parent();
//運行期報錯,java.lang.ClassCastException,多態(tài)在運行器材可以確定是否可以轉(zhuǎn)換
Child child=(Child)parent;
child.test();
}
}
Exception in thread "main" java.lang.ClassCastException: com.xd.map.Parent cannot be cast to com.xd.map.Child
at com.xd.map.Child.main(Child.java:12)
父類不能強轉(zhuǎn)為子類
Child c=new Parent(); x
Child c1=(Child) new Parent();
========================
Parent p=new Child();
p.test();//這是子類
Parent p=(Parent) new Child();//這是子類
Parent p1=(Parent) new Child();//這是子類
12.String,StringBuffer,StringBuilder的區(qū)別與聯(lián)系
可變性:
String當中使用final修飾符數(shù)組 (final char [] value)保存字符串,所以String當中的字符串都是固定的,可以理解為常量,StringBuffer當中也是采用字符數(shù)組(char [] value)保存字符串的,但是他不是final修飾的,故他的長度是可以追加的,是可變的,StringBuilder也是一樣.二者都繼承自AbstractStringBuilder。

安全性:
StringBuffer與StringBuilder都繼承自AbstractStringBuilder,AbstractStringBuilder當中提供了一些方法, expandCapacity、append、insert、indexOf 等公共方法,但是StringBuffer對繼承的方法進行了重寫加鎖,所以是線程安全的,StringBuilder沒有對繼承的方法進行加鎖,所以是線程不安全的。
性能
每次對String進行操作都會生成一個新的String對象,然后將指正指向新的String對象,StringBuffer對象每次都是對StringBuffer本身進行操作,在同等情況下,StringBuilder的新能只比StringBuffer高10%--15%,但卻要付出安全性為代價。
總結(jié)
1.String用來操作少量的數(shù)據(jù)
2.StringBuffer用來操作大量多線程數(shù)據(jù)
3.StringBuilder用來操作大量單線程數(shù)據(jù)
13.自動裝箱與自動拆箱
自動裝箱:基本數(shù)據(jù)類型轉(zhuǎn)換為包裝類
自動拆箱:包裝類自動轉(zhuǎn)換為基本數(shù)據(jù)類型
14.在靜態(tài)方法當中不能直接調(diào)用非靜態(tài)的方法與屬性
在靜態(tài)方法當中調(diào)用非靜態(tài)方法只能通過類對象來調(diào)用,不能通過類名直接調(diào)用
package com.xd.map;
public class Test3 {
int a=10;
public void test() {
System.out.println("=============");
}
public static void main(String[] args) {
Test3 test3=new Test3();
//=============
test3.test();
//10
System.out.println(test3.a);
}
}
15.父類的無參構(gòu)造器的作用
在java當中初始化的時候默認(未使用super()有參調(diào)用)調(diào)用的是父類的無參構(gòu)造器,如果在父類當中定義了一個有參構(gòu)造器,那么子類當中會報錯,因為找不到默認的無參構(gòu)造器
class Parent {
public Parent(int a) {
System.out.println("這是父類的有參構(gòu)造器");
}
public void test() {
System.out.println("這是父類....");
}
}
//報錯Implicit super constructor Parent() is undefined for default constructor. Must define an explicit constructor
public class Child extends Parent {
public void test() {
System.out.println("這是子類...");
}
}
16.import java與javax有什么不同
在剛開始的時候javax是作為Javax的擴展引入的,后來javax逐漸成為了java API的一部分,但是將javax移入java ApI比較麻煩,會破會掉現(xiàn)有的java API源代碼,所以最終決定將javax作為標準java API的一部分,事實上2者沒有區(qū)別只是名字不一樣而已
17.java當中接口與抽象類的區(qū)別是什么?
接口默認是public的(不寫也默認是public的)
1.接口當中的方法默認都是public的(不寫的時候也默認是public),接口當中的屬性默認都是public static final的(不寫的時候也默認是public static final,修改會報錯)。
2.抽象類和普通的類差別不是很大,最大的差別就是抽象類當中可以有抽象方法,抽象類當中的抽象方法必須要顯示的指明,他不像接口一樣如果未顯示指明會報錯
3.接口與抽象類都不可以實例化,但是接口可以聲明,但是必須引用一個實現(xiàn)該接口的對象 從設(shè)計層面來說,抽象是對類的抽象,是一種模板設(shè)計,接口是行為的抽象,是一種行為的規(guī)范。
抽象方法都不能被static,private,synchronized,native修飾
總結(jié)
接口,接口當中的方法,接口當中的屬性都使用public修飾(無論寫不寫)
方法:public abstract 修飾(無論寫不寫)
屬性:public static final 修飾(無論寫不寫)
JDK1.8:
可以在接口當中定義普通方法,普通方法必須使用使用static修飾
static:只能通過接口名調(diào)用
interface Test1 {
public abstract void t1();
public static void t2() {
};
}
public class Test1Impl implements Test1 {
@Override
public void t1() {
// TODO Auto-generated method stub
}
public static void main(String[] args) {
//必須要通過接口名調(diào)用,不能通過實現(xiàn)類調(diào)用
Test1.t2();
}
}
抽象類,
成員變量: 默認default的
成員方法:可以有抽象方法和非抽象方法 ,抽象方法必須要顯示的指定
18.成員 變量與局部變量的區(qū)別
1.成員變量又叫全局變量,可以被權(quán)限修飾符(private ,public 及static)修飾,局部變量從語法形式上是屬于方法的,不能被權(quán)限修飾符(private ,public 及static)修飾,但是局部變量與成員變量都可以被final修飾。當成員變量被static修飾的時候,成員變量就變成了類變量,類變量是類層次的隨著類的加載而加載,普通的常用變量是隨著對象的創(chuàng)建而加載的
2.從變量在內(nèi)存當中的存儲形式上看,成員變量是對象的一部分,存儲在堆當中,局部變量存儲在棧當中。
3.從變量在內(nèi)存中的生存時間上看,成員變量是對象的一部分,隨著對象的創(chuàng)建而創(chuàng)建,局部變量在隨著方法的調(diào)用完畢之后消失
4.成員變量如果沒有被賦初值,則會自動以類型的默認值而賦值(當中使用final修飾的時候必須要賦初值,否則會報錯)

局部變量如果不賦初值,就不會自動賦值,如果輸出就會報錯
public class Test4 {
public static void main(String[] args) {
int a;
System.out.println(a);
}
}

當局部變量使用final修飾的時候,可以不賦初值,只要在后面賦值即可,但是一旦賦值就不可以改變
public class Test4 {
public static void main(String[] args) {
final int a;
a=1;
System.out.println(a);
}
}

19. 創(chuàng)建一個對象用什么運算符?對象實體與對象引用有何不同?
new運算符,new創(chuàng)建對象實例(對象實例在堆內(nèi)存中),對象引用指向?qū)ο髮嵗▽ο笠么娣旁跅?nèi)存中)。一個對象引用可以指向0個或1個對象(一根繩子可以不系氣球,也可以系一個氣球);一個對象可以有n個引用指向它(可以用n條繩子系住一個氣球)。
20.方法的返回值
當返回值類型為void的時候,可以寫成如下的2中形式
package com.xd.map;
public class Test4 {
public void tt(){
return ;
}
public void tt1(){
}
}
21.類的構(gòu)造方法的特新與左右
類的構(gòu)造方法主要是用來完成一些初始化的操作
特性:
1.類名與方法名相同
2.沒有返回值,不能寫成void
3.在new對象的時候自動調(diào)用
22.對象的相等與指向他們的引用相等,兩者有什么不同?
對象的相等,比的是內(nèi)存中存放的內(nèi)容是否相等。而引用相等,比較的是他們指向的內(nèi)存地址是否相等。
23.== 與 equals(重要)
1.==用來判斷2個對象的地址是不是相等,即判斷2個對象是不是同一個對象,(基本數(shù)據(jù)類型判斷的是值是否相等,引用類型判斷的是地址值是否是相等,是否是同一對象)
2.equals()的作用也是判斷2個對象是否相等,但是一般分為如下的2中情況:
(一):
重寫了Object當中的equals()方法,讓他用來比較2個對象的值是否相等
(二):
沒有重寫equals當中的equals()方法,比較的還是地址,與==相同
public class test1 {
public static void main(String[] args) {
String a = new String("ab"); // a 為一個引用
String b = new String("ab"); // b為另一個引用,對象的內(nèi)容一樣
String aa = "ab"; // 放在常量池中
String bb = "ab"; // 從常量池中查找
if (aa == bb) // true
System.out.println("aa==bb");
if (a == b) // false,非同一對象
System.out.println("a==b");
if (a.equals(b)) // true
System.out.println("aEQb");
if (42 == 42.0) { // true
System.out.println("true");
}
}
}
說明:
String 中的 equals 方法是被重寫過的,因為 object 的 equals 方法是比較的對象的內(nèi)存地址,而 String 的 equals 方法比較的是對象的值。
當創(chuàng)建 String 類型的對象時,虛擬機會在常量池中查找有沒有已經(jīng)存在的值和要創(chuàng)建的值相同的對象,如果有就把它賦給當前引用。如果沒有就在常量池中重新創(chuàng)建一個 String 對象。
24.HashCode()與equals()方法
hashCode()的作用是獲取哈希碼,又叫散列碼,他返回的是一個int類型的證整數(shù),這個int值就是這個對象在哈希表當中的索引位置,他的作用是獲取對象在哈希表當中的索引位置。hashCode() 定義在JDK的Object.java中,這就意味著Java中的任何類都包含有hashCode() 函數(shù)。
哈希表是鍵值對的方式存儲的,可以通過鍵快速的找到對應(yīng)的值,(即通過索引快速的找到對應(yīng)的對象)
為什么要有 hashCode
考慮一種情況,當向集合中插入對象時,如何判別在集合中是否已經(jīng)存在該對象了?(注意:集合中不允許重復(fù)的元素存在)
**也許大多數(shù)人都會想到調(diào)用equals方法來逐個進行比較,這個方法確實可行**。但是如果集合中已經(jīng)存在一萬條數(shù)據(jù)或者更多的數(shù)據(jù),如果采用equals方法去逐一比較,效率必然是一個問題。此時hashCode方法的作用就體現(xiàn)出來了,當集合要添加新的對象時,先調(diào)用這個對象的hashCode方法,得到對應(yīng)的hashcode值,實際上在HashMap的具體實現(xiàn)中會用一個table保存已經(jīng)存進去的對象的hashcode值,如果table中沒有該hashcode值,它就可以直接存進去,不用再進行任何比較了;如果存在該hashcode值, 就調(diào)用它的equals方法與新元素進行比較,相同的話就不存了,不相同就散列其它的地址,所以這里存在一個沖突解決的問題,這樣一來實際調(diào)用equals方法的次數(shù)就大大降低了。
hashCode()與equals()的相關(guān)規(guī)定
hashCode值相同并不一定是同一個對象,就好比字典上的第100頁上有“書”,“數(shù)”,“熟”等,100就是hashCode值,“書”,“數(shù)”,“熟”的具體位置就是地址
1.如果2個對象相等,則hashcode值也相同
2.兩個對象相等,對兩個對象分別調(diào)用equals方法都返回true
3.兩個對象有相同的hashcode值,它們也不一定是相等的
4.因此,equals 方法被覆蓋過,則 hashCode 方法也必須被覆蓋
25.為什么Java中只有值傳遞?
在程序設(shè)計語言當中有2種參數(shù)值的傳遞方式:按值傳遞:表示方法接收的是調(diào)用者提供的值,按引用對象傳遞:表示方法接收的是調(diào)用者提供的變量地址
方法接收的是調(diào)用者提供的值
public static void main(String[] args) {
int num1 = 10;
int num2 = 20;
swap(num1, num2);
System.out.println("num1 = " + num1);
System.out.println("num2 = " + num2);
}
public static void swap(int a, int b) {
int temp = a;
a = b;
b = temp;
System.out.println("a = " + a);
System.out.println("b = " + b);
}
結(jié)果
a = 20
b = 10
num1 = 10
num2 = 20

在swap方法中,a、b的值進行交換,并不會影響到 num1、num2。因為,a、b中的值,只是從 num1、num2 的復(fù)制過來的。也就是說,a、b相當于num1、num2 的副本,副本的內(nèi)容無論怎么修改,都不會影響到原件本身。
而<b>對象引用<b>作為參數(shù)就不一樣
public static void main(String[] args) {
int[] arr = { 1, 2, 3, 4, 5 };
System.out.println(arr[0]);
change(arr);
System.out.println(arr[0]);
}
public static void change(int[] array) {
// 將數(shù)組的第一個元素變?yōu)?
array[0] = 0;
}
結(jié)果:
1
0

array 被初始化 arr 的拷貝也就是一個對象的引用,也就是說 array 和 arr 指向的時同一個數(shù)組對象。 因此,外部對引用對象的改變會反映到所對應(yīng)的對象上。
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
Student s1 = new Student("小張");
Student s2 = new Student("小李");
Test.swap(s1, s2);
System.out.println("s1:" + s1.getName());
System.out.println("s2:" + s2.getName());
}
public static void swap(Student x, Student y) {
Student temp = x;
x = y;
y = temp;
System.out.println("x:" + x.getName());
System.out.println("y:" + y.getName());
}
}
結(jié)果:
x:小李
y:小張
s1:小張
s2:小李


26. 簡述線程,程序、進程的基本概念。以及他們之間關(guān)系是什么?
程序在執(zhí)行的時候,將會被操作系統(tǒng)載入到內(nèi)存當中
線程:線程是最小的進程,一個進程可以有許多的線程,同類的多個線程共享同一塊內(nèi)存空間與同一組系統(tǒng)資源,當系統(tǒng)產(chǎn)生一個線程,在各個線程之間切換工作時,負擔要比進程小的多(共享同一內(nèi)存空間,訪問同一組系統(tǒng)資源),所以線程又叫輕量級進程。
程序:含有指令與數(shù)據(jù)的文件,被存儲在磁盤或者其他的存儲設(shè)備當中,冶金是說程序是靜態(tài)的代碼
進程:程序的一次執(zhí)行過程,因此進程是動態(tài)的,系統(tǒng)運行一個程序即是一個進程從創(chuàng)建(new),運行到銷毀的過程。簡單來說,進程是執(zhí)行當中的程序,他在計算機當中一個指令接著一個指令的執(zhí)行,同時各個進程都會棧有不同的內(nèi)存與系統(tǒng)資源,各個進程所占有的東西是獨立的。
27.線程有哪些基本的狀態(tài)?他們是怎么定義的?
1.創(chuàng)建(new):新建一個線程對象
2.可運行(runnable):線程對象創(chuàng)建之后,其他的線程(比如main線程),調(diào)用了該對象的start()方法,該狀態(tài)的線程位于可運行線程池當中,等待線程調(diào)度的選中,獲取CPU的使用權(quán)(獲取時間片)。
3.運行(running):可運行狀態(tài)的線程,被線程調(diào)度選中,獲得了CPU的使用權(quán),執(zhí)行程序代碼。
4.阻塞(block):運行當中的線程因為某些原因放棄了CPU的使用權(quán),退出了時間片,暫時停止運行,直到該線程進入可運行狀態(tài)(runnable)狀態(tài),才有 機會再次獲得cpu timeslice轉(zhuǎn)到運行(running)狀態(tài)。
阻塞的情況一般分為3種:
(等待阻塞):運行當中的線程執(zhí)行wait()方法,JVM會把線程放入等待隊列當中.
(同步阻塞):運行當中的線程在獲取對象的同步鎖的時候,該同步鎖被其他的線程所占用,JVM會把給線程放入到鎖池(lock pool)當中.
(其他阻塞):運行當中的線程執(zhí)行sleep(),或者join(),或者發(fā)出I/O請求的時候,JVM會將該線程至為阻塞狀態(tài),當sleep(),join(),I/O超時或者完畢之后,會重新進入runnable狀態(tài)。
5.死亡(dead):當run方法執(zhí)行完畢,或者main方法執(zhí)行完畢,或者run方法因為異常執(zhí)行完畢,此時線程死亡,線程死亡之后不可恢復(fù)。

備注: 可以用早起坐地鐵來比喻這個過程:
還沒起床:sleeping
起床收拾好了,隨時可以坐地鐵出發(fā):Runnable
等地鐵來:Waiting
地鐵來了,但要排隊上地鐵:I/O阻塞
上了地鐵,發(fā)現(xiàn)暫時沒座位:synchronized阻塞
地鐵上找到座位:Running
到達目的地:Dead
wait()、notify()和notifyAll()是 Object類 中的方法 ;
Condition是在java 1.5中才出現(xiàn)的,它用來替代傳統(tǒng)的Object的wait()、notify()實現(xiàn)線程間的協(xié)作,相比使用Object的wait()、 notify(),使用Condition1的await()、signal()這種方式實現(xiàn)線程間協(xié)作更加安全和高效。
28.final關(guān)鍵詞的一些總結(jié)
final可以用來修飾,類,方法,變量
修飾類:類不可繼承,final類中的所有成員方法都會被隱式地指定為final方法。
修飾方法:方法不可重寫
修飾變量:對于一個final變量,如果是基本數(shù)據(jù)類型的變量,則其數(shù)值一旦在初始化之后便不能更改;如果是引用類型的變量,則在對其初始化之后便不能再讓其指向另一個對象,如果是全局變量必須要在聲明的時候指定初始值,如果是局部變量,可以在后面指定初始值
29.java當中的異常處理
Java異常類層次結(jié)構(gòu)圖

在 Java 中,所有的異常都有一個共同的祖先java.lang包中的 Throwable類。Throwable: 有兩個重要的子類:Exception(異常) 和 Error(錯誤) ,二者都是 Java 異常處理的重要子類,各自都包含大量子類。
Error(錯誤):是程序無法處理的錯誤,表示運行應(yīng)用程序中較嚴重問題。大多數(shù)錯誤與代碼編寫者執(zhí)行的操作無關(guān),而表示代碼運行時 JVM(Java 虛擬機)出現(xiàn)的問題。例如,Java虛擬機運行錯誤(Virtual MachineError),當 JVM 不再有繼續(xù)執(zhí)行操作所需的內(nèi)存資源時,將出現(xiàn) OutOfMemoryError。這些異常發(fā)生時,Java虛擬機(JVM)一般會選擇線程終止。
這些錯誤表示故障發(fā)生于虛擬機自身、或者發(fā)生在虛擬機試圖執(zhí)行應(yīng)用時,如Java虛擬機運行錯誤(Virtual MachineError)、類定義錯誤(NoClassDefFoundError)等。這些錯誤是不可查的,因為它們在應(yīng)用程序的控制和處理能力之 外,而且絕大多數(shù)是程序運行時不允許出現(xiàn)的狀況。對于設(shè)計合理的應(yīng)用程序來說,即使確實發(fā)生了錯誤,本質(zhì)上也不應(yīng)該試圖去處理它所引起的異常狀況。在 Java中,錯誤通過Error的子類描述。
Exception(異常):是程序本身可以處理的異常。Exception 類有一個重要的子類 RuntimeException。RuntimeException 異常由Java虛擬機拋出。NullPointerException(要訪問的變量沒有引用任何對象時,拋出該異常)、ArithmeticException(算術(shù)運算異常,一個整數(shù)除以0時,拋出該異常)和 ArrayIndexOutOfBoundsException (下標越界異常)。
注意:異常和錯誤的區(qū)別:異常能被程序本身可以處理,錯誤是無法處理。
Throwable類常用方法
public string getMessage():返回異常發(fā)生時的詳細信息
public string toString():返回異常發(fā)生時的簡要描述
public string getLocalizedMessage():返回異常對象的本地化信息。使用Throwable的子類覆蓋這個方法,可以聲稱本地化信息。如果子類沒有覆蓋該方法,則該方法返回的信息與getMessage()返回的結(jié)果相同
public void printStackTrace():在控制臺上打印Throwable對象封裝的異常信息
異常處理總結(jié)
try 塊:用于捕獲異常。其后可接零個或多個catch塊,如果沒有catch塊,則必須跟一個finally塊。
catch 塊:用于處理try捕獲到的異常。
finally 塊:無論是否捕獲或處理異常,finally塊里的語句都會被執(zhí)行。當在try塊或catch塊中遇到return語句時,finally語句塊將在方法返回之前被執(zhí)行。
在以下4種特殊情況下,finally塊不會被執(zhí)行:
在finally語句塊中發(fā)生了異常。
在前面的代碼中用了System.exit()退出程序。
程序所在的線程死亡。
關(guān)閉CPU。
30.java當中有些字段不想被序列化,怎么辦?
對于不想被序列化的字段,可以使用transient修飾。
transient關(guān)鍵字的作用是:阻止實例中那些用此關(guān)鍵字修飾的的變量序列化;當對象被反序列化時,被transient修飾的變量值不會被持久化和恢復(fù)。transient只能修飾變量,不能修飾類和方法。
31.獲取鍵盤輸入值的2種方法
(一)通過scanner
package com.xd.map;
import java.util.Scanner;
public class Test5 {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
String str=input.nextLine();
System.out.println(str);
}
}
(二)通過BufferedReader方法
package com.xd.map;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Test5 {
public static void main(String[] args) throws IOException {
BufferedReader input=new BufferedReader(new InputStreamReader(System.in));
String str=input.readLine();
System.out.println(str);
}
}
32.java當中的內(nèi)存結(jié)構(gòu)分析
說明:常量與靜態(tài)的變量,方法存放在方法區(qū),其他的普通成員變量存放在堆區(qū)
圖解說明
package com.xd.map;
class Car{
public String name;
public String color;
public float price;
public void say() {
System.out.println("買車花費總價");
}
}
public class Test6 {
public static void main(String[] args) {
Car car=new Car();
}
}
此時在內(nèi)存空間當中的圖示如下:

package com.xd.map;
class Car{
public String name;
public String color;
public float price;
public void say() {
System.out.println("買車花費總價");
}
}
public class Test6 {
public static void main(String[] args) {
Car car=new Car();
car.color="黃色";
car.name="大黃蜂";
car.price=1000000;
}
}

package com.xd.map;
class Car{
public String name;
public String color;
public float price;
public void say() {
System.out.println("買車花費總價");
}
}
public class Test6 {
public static void main(String[] args) {
Car car=new Car();
car.color="黃色";
car.name="大黃蜂";
car.price=1000000;
car.say();
}
}
