數據類型 | 大小/bit |
---|---|
byte | 8位 |
short | 16位 |
int | 32位 |
long | 64位 |
float | 32位 |
double | 64位 |
char | 16位 |
boolean | 1位 |
可變與不可變html
private final char value[];
char[] value;
是否線程安全java
public synchronized StringBuffer reverse() { super .reverse(); return this ; } public int indexOf(String str) { return indexOf(str, 0); //存在 public synchronized int indexOf(String str, int fromIndex) 方法 }
當char[] 數組大小即capacity不足時,StringBuilder的擴容爲原來的capacity*2+2;編程
public final native Class<?> getClass() public native int hashCode() public boolean equals(Object obj) protected native Object clone() throws CloneNotSupportedException public String toString() public final native void notify() public final native void notifyAll() public final native void wait(long timeout) throws InterruptedException public final void wait(long timeout, int nanos) throws InterruptedException public final void wait() throws InterruptedException protected void finalize() throws Throwable {}
對任何不是null的對象x調用x.equals(null)結果都爲false。數組
Integer x = new Integer(1); Integer y = new Integer(1); System.out.println(x.equals(y)); // true System.out.println(x == y); // false
public class EqualExample { private int x; private int y; private int z; public EqualExample(int x, int y, int z) { this.x = x; this.y = y; this.z = z; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; EqualExample that = (EqualExample) o; if (x != that.x) return false; if (y != that.y) return false; return z == that.z; } }
hashCode()返回散列值,而equals()是用來判斷兩個實例是否等價,等價的兩個實例散列值必定要相等,可是散列值相同的兩個實例不必定等價。緩存
在覆蓋equals()方法時應當老是覆蓋hashCode()方法,保證等價的兩個實例散列值也相等。安全
下面代碼中,新建了兩個等價的實例,並將它們添加到HashSet中,咱們但願將這兩個實例當成同樣的,只在集合中添加一個實例,可是由於EqualExample沒有實現hashCode()方法,所以這兩個實例的散列值是不相同的,最終致使集合添加了兩個等價的實例。網絡
EqualExample e1 = new EqualExample(1, 1, 1); EqualExample e2 = new EqualExample(1, 1, 1); System.out.println(e1.equals(e2)); // true HashSet<EqualExample> set = new HashSet<>(); set.add(e1); set.add(e2); System.out.println(set.size()); // 2
理想的散列函數應當具備均勻性,既不相等的實例應當分佈在全部可能的散列值上。這就要求散列值要把全部的值都考慮進來,能夠將每一個域都當成R進制的某一位,而後組成一個R進程的整數。R通常取31,由於它是一個奇素數,若是是偶數的話,當出現乘法溢出,信息會丟失,由於與2相乘至關於向左移一位。app
一個數與 31 相乘能夠轉換成移位和減法:31*x == (x<<5)-x,編譯器會自動進行這個優化。ide
@Override public int hashCode() { int result = 17; result = 31 * result + x; result = 31 * result + y; result = 31 * result + z; return result; }
默認返回ToStringExample@4554617c 這種形式,其中@後面的數值爲散列值的無符號十六進制表示。函數
public class ToStringExample { private int number; public ToStringExample(int number) { this.number = number; } } ToStringExample example = new ToStringExample(123); System.out.println(example.toString()); ToStringExample@4554617c
clone()是Object的protect方法,它不是public,一個類不顯示區重寫clone(),其餘類就不能直接去調用該類實例的clone()方法。
public class CloneExample { private int a; private int b; } CloneExample e1 = new CloneExample(); // CloneExample e2 = e1.clone(); // 'clone()' has protected access in 'java.lang.Object'
重寫clone()獲得如下實現:
public class CloneExample { private int a; private int b; @Override protected CloneExample clone() throws CloneNotSupportedException { return (CloneExample)super.clone(); } } CloneExample e1 = new CloneExample(); try { CloneExample e2 = e1.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } java.lang.CloneNotSupportedException: CloneExample
以上拋出了CloneNotSupportedException,這個由於CloneExample沒有實現Cloneable接口。
public class CloneExample implements Cloneable { private int a; private int b; @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }
應該注意的是,clone()方法並非Cloneable接口的方法,而是Object的一個protect方法。Cloneable接口只是規定,若是一個類沒有實現Cloneable接口又調用了clone()方法,就會拋出CloneNotSupportException。
public class ShallowCloneExample implements Cloneable { private int[] arr; public ShallowCloneExample() { arr = new int[10]; for (int i = 0; i < arr.length; i++) { arr[i] = i; } } public void set(int index, int value) { arr[index] = value; } public int get(int index) { return arr[index]; } @Override protected ShallowCloneExample clone() throws CloneNotSupportedException { return (ShallowCloneExample) super.clone(); } } ShallowCloneExample e1 = new ShallowCloneExample(); ShallowCloneExample e2 = null; try { e2 = e1.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } e1.set(2, 222); System.out.println(e2.get(2)); // 222
public class DeepCloneExample implements Cloneable { private int[] arr; public DeepCloneExample() { arr = new int[10]; for (int i = 0; i < arr.length; i++) { arr[i] = i; } } public void set(int index, int value) { arr[index] = value; } public int get(int index) { return arr[index]; } @Override protected DeepCloneExample clone() throws CloneNotSupportedException { DeepCloneExample result = (DeepCloneExample) super.clone(); result.arr = new int[arr.length]; for (int i = 0; i < arr.length; i++) { result.arr[i] = arr[i]; } return result; } } DeepCloneExample e1 = new DeepCloneExample(); DeepCloneExample e2 = null; try { e2 = e1.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } e1.set(2, 222); System.out.println(e2.get(2)); // 2
使用clone()方法來拷貝一個對象即複雜又有風險,它會拋出異常,而且還須要類型轉換。最好不要去使用clone()而是使用拷貝構造函數或者拷貝工廠來拷貝一個對象。
public class CloneConstructorExample { private int[] arr; public CloneConstructorExample() { arr = new int[10]; for (int i = 0; i < arr.length; i++) { arr[i] = i; } } public CloneConstructorExample(CloneConstructorExample original) { arr = new int[original.arr.length]; for (int i = 0; i < original.arr.length; i++) { arr[i] = original.arr[i]; } } public void set(int index, int value) { arr[index] = value; } public int get(int index) { return arr[index]; } } CloneConstructorExample e1 = new CloneConstructorExample(); CloneConstructorExample e2 = new CloneConstructorExample(e1); e1.set(2, 222); System.out.println(e2.get(2)); // 2
利用抽象數據類型將數據和基本數據的操做封裝在一塊兒,使其構成一個不可分割的獨立實體。數據被保護在抽象數據類型的內部,儘量地隱藏內部的細節,只保留一些對外接口與外部發生聯繫。
繼承實現了 IS-A 關係,例如 Cat 和 Animal 就是一種 IS-A 關係,所以 Cat 能夠繼承自 Animal,從而得到 Animal 非 private 的屬性和方法。
繼承應該遵循里氏替換原則,子類對象必須可以替換掉全部父類對象。
多態分爲編譯時多態和運行時多態,編譯時多態指方法的重載,運行時多態指程序中定義的對象引用所指向的具體類型在運行時才肯定。
運行時多態的三個條件:
如:
樂器類(Instrument)有兩個子類:Wind 和 Percussion,它們都覆蓋了父類的 play() 方法,而且在 main() 方法中使用父類 Instrument 來引用 Wind 和 Percussion 對象。在 Instrument 引用調用 play() 方法時,會執行實際引用對象所在類的 play() 方法,而不是 Instrument 類的方法。
每一個內部裏都能獨立地繼承一個(接口的)實現因此不管外圍類是否已經繼承了某個(接口的)實現,對於內部類都沒有影響。
在咱們程序設計中有時候會存在一些使用接口很難解決的問題,這個時候咱們能夠利用內部類提供的、能夠繼承多個具體的或者抽象的類的能力來解決這個程序設計問題。
也就是說接口只是解決了部分問題,而內部類使用多重繼承的解決方案變得更加完整。
類型參數<T>,無解通配符<?>
新的輸入/輸出庫是JDK1.4中引入的,彌補了原來的I/O的不足,提供了高速的、面向塊的I/O.
I/O跟NIO最重要的區別是數據打包和傳輸的方式,I/O以流的方式處理數據,而NIO以塊的方式處理數據。
面向流的I/O一次處理一個字節數據,一個輸入流產生一個字節數據,一個輸出流產生一個字節數據。爲流式建立過濾器很是容易,連接幾個過濾器,以便每一個過濾器只負責處理機制的一部分。不利的一面是,面向流的I/O一般至關慢。
面向塊的I/O一個處理一個數據塊,按塊處理數據比按流處理數據要快得多。可是面向塊的I/O缺乏一些面向流的I/O所具備的優雅性和簡單性。
I/O包和NIO已經很好地集成了,java.io.已經以NIO爲基礎從新實現了,因此如今它能夠利用NIO的一些特性,例如:java.io.包中的一些類包含以塊的形式讀寫數據的方法,這使得即便在面向流的系統中,處理速度也會更快。
通道Channel是對原來I/O包中的流的模擬,能夠經過它讀取和寫入數據。
通道與流的不一樣之處在於,流只能在一個方向上移動(一個流必須是InputStream或者OutputStream的子類),而通道是雙向的,能夠用於讀、寫或者同時讀寫。
通道包括如下類型:
發送給一個通道的全部數據都必須先通過緩衝區,一樣地,從通道中讀取的任何數據都要先讀到緩衝區中。也就是說,不會直接對通道進行讀寫數據,而是要先通過緩衝區。
緩衝區實質上是一個數組,但它不只僅是一個數組。緩衝區提供了對數據的結構化訪問,並且還能夠跟蹤系統的讀/寫進程。
緩衝區的類型:
JDK5.0中的類型:類、接口、枚舉、註解。註解是跟其餘三種類型同樣,均可以定義、使用,以及包含本身的屬性。
負責註解其餘註解
做用:定義註解的使用範圍
取值:(ElementType)
做用:該註解的保留時間
取值:(RetantionPoicy)
做用:用於描述其餘類型的註解應該被標註爲程序成員的API,所以能夠被javadoc此類的工具文檔化。是一個標記註解,沒有成員。
做用:@Inherited 元註解是一個標記註解,@Inherited闡述了某個被標註的類型是被繼承的。若是一個使用了@Inherited修飾的annotation類型被用於一個class,則這個annotation將被用於該class的子類。
不是特別瞭解,再補上
默認數組大小爲10,當超出數組大小時,1.5擴容,vector擴容元數組的2倍。
代理對象和目標對象實現了相同的接口,目標對象做爲代理對象的一個屬性,具體的實現接口中,能夠在調用目標對象相應方法先後加上其餘業務處理邏輯。
CGLIB代理是針對類實現代理。
主要是對指定的類生成一個子類,覆蓋起全部方法,因此該類或方法不能聲明爲final。
AOP(Aspect-OrientedProgramming,面向切面編程),AOP包括切面(aspect)、通知(advice)、鏈接點(joinpoint),實現方式就是經過對目標對象的代理在鏈接點先後加入通知,完成統一的切面操做。