內部類
當我們在描述一個事物的時候發現,該事物中有存在另一個事物,那麼將後者稱之爲內部類,前者稱之爲外部類。就如在前面介紹的鏈棧結構,鏈表和結點就是這樣的關係。鏈表是由結點組成,所以結點類是鏈表的內部類,而鏈表是結點的外部內。
但是之前都是在該外部類裏面對內部類進行操作的,那麼如何在外部類的外面對內部類進行操作呢?下面一 一介紹:
首先展示一下內部類的表現形式:
class Outer{ //外部類
int age=20; //外部類的屬性
String name = "Bob";
class Inner{ //非靜態內部類
int age=10; //內部類的非靜態屬性
void show(){ //內部類的非靜態方法
System.out.println("inner show...");
}
}
static class Inner2{ //靜態內部類
int age=10;
public static String name = "marry"; //內部類的靜態屬性
public static void show2(){ //內部類的靜態方法
System.out.println("inner show...");
}
}
}
1.如何訪問非靜態內部類中的成員?
雖然非靜態內部類Inner是一個類,但還是定義在外部類Outer中的,相當於還是外部類中的一個非靜態成員,那麼這就簡單化,一般我們在主類中要訪問到某實體類中的成員,會在主類中創建該實體類的對象,然後用對象去調用該類中的成員。但是現在我們是想訪問到內部類中的成員,就必須創建內部類的對象,通過外部類的對象我們可以訪問到內部類,因此在內部類存在的情況下,想要獲得內部類的對象就要先創建外部類的對象,所以我們可以通過以下辦法來訪問非靜態內部類中的成員;
public class Main{
public static void main(String[] args) {
Outer.Inner in=new Outer().new Inner(); // Outer.Inner聲明的是Outer類裏面的Inner類的對象
//new Outer()先創建外部類的對象.new Inner()再創建內部類的對象
System.out.println(in.age); //用該對象可以在外部類外訪問內部類中的成員
in.show();
}
}
2.如何訪問靜態內部類中的靜態成員?
靜態是隨着類加載而必須加載的,所以在外部類加載進來的時候,靜態內部類和它的靜態成員隨着一起加載進來,因此不需要對象來進行調用,直接可以用類名調用即可:
public class Main{
public static void main(String[] args) {
System.out.println(Outer.Inner2.name); //Outer.Inner這裏還是要指明是哪個類中的內部類中的靜態成員
Outer.Inner2.show2();
}
}
一旦內部類中存在靜態成員,該內部類就必須是靜態的,因爲如果是非靜態內部類中存在靜態的方法話,靜態方法要隨內部類加載而加載進入到靜態方法區,但是該內部類是非靜態的必須要隨着對象的加載而加載,因此矛盾了,所以只能靜態內部類中才能有靜態成員。
3.如何訪問靜態內部類中的非靜態成員?
現在內部類是靜態的,可以直接用外部類的類名調用訪問,但是調用內部類中非靜態的成員還是需要內部類的對象的,因此可以使用一下方法進行訪問:
public class Main{
public static void main(String[] args){
Outer.Inner2 in=new Outer.Inner2(); //Outer.Inner2這裏指明是Outer類中的Inner2類
//創建對象時Outer.Inner2()只調用了Inner2()的構造方法,說明只創建了內部類的對象
System.out.println(in.age);
}
}
如果內部類和外部類有屬性重名,那麼外部類直接調用外部類的屬性,通過創建內部類對象調用內部類屬性;內部類則是先調用自己內部的屬性,如果內部沒有該屬性,就調用外部類的屬性。
object類
object類是Java.lang包下的一個類,打開API,找到該類,我們可以看到
所有的類都會實現這個類的方法,它是所有類的父類,就算沒有明顯的繼承的關係,我們在定義一個類的時候還是默認的繼承了我們的object類。向下翻找,找到該類的方法:
它的方法相對較說還是比較少的,現在將常用的進行介紹:
clone() 方法
是複製一個對象,創建一個新的對象,然後將這個新的對象賦值給另一個數據類型相同的引用,這樣就創建了兩個內容相同的不同對象。它有兩種實現——深克隆和淺克隆:
淺克隆:調用object的clone()方法,重新創建一個對象,將要複製的對象中的值或者引用複製到新創建的對象中去,這樣兩個對象就不同了,但是如果將對象裏面的引用類型變量值複製過去,則兩個變量還是指的相同的對象,這裏就要用到深克隆;
深克隆:不僅將外面的對象重新創建一個,還會將內部的對象引用也會重新創建並把值複製過去,但是這裏要實現Cloneable 和 Comparable兩個接口,重寫clone方法,將內部的對象引用也要進行復制。
如定義一個Hose類,下面是深克隆和淺克隆的示意圖:
equals()方法
該方法默認比的是兩個對象引用的地址,這在介紹String類時已經介紹過了,這裏就不詳細描述了。
finalize()方法
當我們的對象再被垃圾回收的時候調用該方法(gc調用),不需要外界調用,也就是說,當我們創建一個對象在程序結束後內存中會自動清理我們運行時產生的垃圾,以免內存被佔滿。
getClass()方法是獲取當前類,是反射裏面的內容,這裏先不介紹,知道會用就行。
hashCode()方法
該方法在源碼中的編碼是這樣的:
native表示本地(底層C語言), 返回的是該對象在內存中真實的物理地址(是以十進制存儲的),在這裏用到了哈希編碼,在以後hashcode用來計算對象在哈希表中索引,這將在介紹hash碼的時候詳細描述,這裏簡單介紹一下。
當我們在存儲一個內容的時候如123,系統當中有它相應的算法將該內容編碼成哈希碼,然後存在數組中與該哈希碼一樣的位置下標中,那麼問題來了,如果我們在存儲一個213,假設兩個哈希碼值一樣,但是內容表示的意義是不一樣的,該如何盡心存貯呢?這就引入哈希碼的結構如下:
這就是哈希表的存儲方式,所有在獲得兩個對象的哈希碼值時,可能會相等。
notify() 、notifyAll()、wait()都是在線程中的內容,放在後面介紹
最後一個是
toString()方法
將對象的字符串表現形式返回,該方法在源碼中的編碼是這樣的:類名+地址
所以在我們定義的類中如果沒有重寫toString方法就調用該方法,得到的就是該對象的類名和哈希碼值。
Integer類
integer類是int數據類型的包裝類,該
類在對象中包裝了一個基本類型 int
的值,Integer
類型的對象包含一個 int
類型的字段。此外,該類提供了多個方法,能在 int
類型和 String
類型之間互相轉換,還提供了處理 int
類型時非常有用的其他一些常量和方法。在API中它的方法有:
不看不知道,一看嚇一跳,好多方法啊,其實常用的也就那幾個,其中特殊的幾點:
1、拆箱和裝箱的概念
int i1=3;
int i2=6;
//裝箱:將基本數據類型包裝爲對象
Integer i3=3; //相當於new Integer(3),與string類一樣
Integer i4=6; //new Integer(6)
//拆箱:當包裝類型和基本類比較時,包裝類型下轉
//i3存的是對象的地址 但是i3發現和i1基本數據類型比,所以i3將其內部的基本類型數據拿出來和i1比
System.out.println(i1==i3); //結果爲true
System.out.println(i2==i4); //同理
//i3 和 i4已經是對象 所以比的是對象的地址
System.out.println(i3==i4); //結果爲true
2、在Integer中如果 Integer a=n(0~127) 則共享相應值的對象,所以:
Integer i7=10; //new Integer(10)
Integer i8=10; //new Integer(10)
System.out.println(i7==i8); //結果爲true
Integer i9=128; //new Integer(128)
Integer i10=128; //new Integer(128)
System.out.println(i9==i10); //結構爲false
因此,在比較兩個對象的內容是否相等的時候,一定要用equals方法進行比較。
3.介紹幾個比較好用的方法,平時寫代碼時也用的比較多
1)將數字字符串轉整型int數字,默認十進制 —— Integer.parseInt("123")
2) 以 int
類型返回該 Integer
的值 —— i9.intValue()+10
3)將數字字符串轉整型int數字以2~36進制解析,出來的結果是十進制 —— Integer.parseInt("a123f", 2~36)
4)以二進制(基數 2)無符號整數形式返回一個整數參數的字符串表示形式 —— toBinaryString(int i)【還有八進制和十六進制】
Character類
該類是char類型的包裝類,主要有一下幾種常用方法:
1)確定指定字符是否爲數字 —— isDigit(char ch)
2)確定指定字符是否爲字母 ——isLetter(char ch)
3)確定指定字符是否爲字母或數字 ——isLetterOrDigit(char ch)
4)確定指定字符是否爲大寫字母 ——isUpperCase(char ch)
5)確定指定字符是否爲小寫字母 ——isLowerCase(char ch)
其他基本數據類型所對應的類:
byte Byte
short Short
long Long
float Float
double Double
boolea Boolean