Java知識整理
- 概念問題
- 面向對象和麪向過程
- Java和C++
- Java 語言特點
- JDK 和 JRE和JVM
- Oracle JDK 和 OpenJDK
- 字符型常量和字符串常量
- 構造器 Constructor 是否可被 override
- override重寫和overload重載
- 面向對象三大特性: 封裝 繼承 多態
- String 、 StringBuffer 和 StringBuilder
- 自動裝箱與拆箱
- 定義一個不做事且沒有參數的構造方法的作用
- java和javax:javax包成爲標準一部分
- 接口和抽象類
- 基本與包裝類型使用標準
- 自動裝箱
- equlas注意事項
- 成員變量與局部變量
- == 與 equals
- hashCode 與 equals
- 線程、程序、進程
- 線程基本狀態
- final關鍵字
- 異常處理
- Throwable類常用方法
- 字段不希望序列化
- 獲取用鍵盤輸入
- 內部類
- staic
- I/O流
- BIO、NIO、AIO
- 淺拷貝和深拷貝
- Collection
- Arrays操作
- BigDecimal的用處
- Arrays.asList使用
- 正確將數組轉化爲ArrayList
- Collection.toArray轉爲數組
- 泛型限定
- 泛型數組(重點)
- 可重入/不可重入鎖
- 樂觀鎖、悲觀鎖
概念問題
面向對象和麪向過程
Java和C++
Java 語言特點
JDK 和 JRE和JVM
Oracle JDK 和 OpenJDK
字符型常量和字符串常量
構造器 Constructor 是否可被 override
override重寫和overload重載
面向對象三大特性: 封裝 繼承 多態
String 、 StringBuffer 和 StringBuilder
自動裝箱與拆箱
定義一個不做事且沒有參數的構造方法的作用
java和javax:javax包成爲標準一部分
接口和抽象類
- 方法:接口默認public,不可實現;抽象類可有非抽象方法
- 變量:接口只能有static和final
- 一個類可多接口,單抽象類
- 理念:抽象類是模板;接口是行爲抽象。
public interface DoSomething {
static String name="null";
final String type="animal type";
String getAnimalName();
}
public interface EatSomething {
String eat();
}
public abstract class Animal {
abstract public String getName();
public String getType(){
return "not a human";
}
}
public class Dog extends Animal implements DoSomething,EatSomething {
@Override
public String getName() {
return null;
}
@Override
public String getAnimalName() {
return null;
}
@Override
public String eat() {
return null;
}
}
JDK8中,接口可定義靜態方法。
public interface EatSomething {
String eat();
static String getPlaceName() {
return "house";
}
}
基本與包裝類型使用標準
- POJO類必須使用包裝數據類型。
- RPC方法返回值和參數必須使用包裝類型。
- 局部變量使用基本數據類型。
NPE問題:Null Pointer Exception空指針例外。Integer的null和0表示不同意思,而int沒有null,就無法區分意思。
自動裝箱
自動裝箱創建Integer對象,數值在-128~127,將創建的Integer緩存起來,下次再出現該數值,直接從緩存去對象。
(IDEA阿里巴巴的p3c插件會檢測==錯誤)。
int x=3;
int y=3;
System.out.println("x==y:"+(x==y));
Integer x1=new Integer(3);
Integer y1=new Integer(3);
System.out.println("x1==y1:"+(x1==y1));
System.out.println("x1.equals(y1):"+(x1.equals(y1)));
上面x和y引用的是相同的對象。
equlas注意事項
jdk7引入Objects.equals(…,…)更好地避免equals調用出錯。
成員變量與局部變量
== 與 equals
public class Test {
public static void main(String[] args) {
String s = new String("nihao");
String s1 = new String("nihao");
System.out.println("s==s1:"+(s==s1));
System.out.println("s.equals(s1):"+(s.equals(s1)));
}
}
結果:
特殊情況:常量池的作用
String aa = "ab"; // 放在常量池中
String bb = "ab"; // 從常量池中查找
String aa="ab";
String bb="ab";
System.out.println("aa==bb:"+(aa==bb));
System.out.println("aa.equals(bb):"+(aa.equals(bb)));
結果:
hashCode 與 equals
String s = new String("nihao");
String s1=new String("nihao");
System.out.println("s:"+s);
System.out.println("s1:"+s1);
System.out.println("s.equals(s1):"+(s.equals(s1)));
System.out.println("s.hashcode:"+s.hashCode());
System.out.println("s1.hashcode:"+s1.hashCode());
結果:
重點注意: equals 方法被覆蓋過,則 hashCode 方法也必須被覆蓋。
如果hashcode相同,則比較equals。
線程、程序、進程
線程基本狀態
final關鍵字
- 變量
- 方法(方法鎖定,以防任何繼承類修改它的含義;第二個原因是效率)。
- 類(類不能被繼承)
異常處理
- Error(錯誤):是程序無法處理的錯誤。
- Exception(異常):是程序本身可以處理的異。
- 注意:異常和錯誤的區別:異常能被程序本身處理,錯誤是無法處理。
Throwable類常用方法
public class MyThrowable extends Throwable {
//返回異常發生時的簡要描述
@Override
public String getMessage() {
return "wait,這裏可能出現了問題";
}
//返回異常發生時的詳細信息
@Override
public String toString() {
return "我的異常類";
}
//返回異常對象的本地化信息。
// 使用Throwable的子類覆蓋這個方法,可以生成本地化信息。
// 如果子類沒有覆蓋該方法,則該方法返回的信息與getMessage()
// 返回的結果相同
@Override
public String getLocalizedMessage() {
return this.getMessage();
}
//在控制檯上打印Throwable對象封裝的異常信息
@Override
public void printStackTrace() {
super.printStackTrace();
}
}
public static void main(String[] args) {
try{
throw new MyThrowable();
}catch (MyThrowable myThrowable){
myThrowable.printStackTrace();
System.out.println("-----------------------");
System.out.println(myThrowable.getMessage());
System.out.println(myThrowable.toString());
}
}
結果:
- try:其後可接零個或多個catch塊,如果沒有catch塊,則必須跟一個finally塊。
- catch:用於處理try捕獲到的異常
- finally:無論是否捕獲或處理異常,finally塊裏的語句都會被執行。當在try塊或catch塊中遇到return 語句時,finally語句塊將在方法返回之前被執行。
catch (MyThrowable myThrowable){
....
return;
}
finally {
System.out.println("你必須執行我finally不可");
}
結果爲:
字段不希望序列化
transient關鍵字,阻止實例中那些用此關鍵字修飾的的變量序列化;
獲取用鍵盤輸入
兩種方式
Scanner scanner = new Scanner(System.in);
String s = scanner.nextLine();
System.out.println(s);
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String s1 = reader.readLine();
System.out.println(s1);
內部類
- 成員內部類
//靜態內部類
Circle.Draw draw = new Circle.Draw();
//非靜態內部類
Circle circle = new Circle(1);
Circle.Made made = circle.new Made();
- 局部內部類
- 靜態內部類
- 匿名內部類
scan_bt.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
}});
history_bt.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {}});
與以上匿名內部類相同的作用代碼爲:
private void setListener()
{
scan_bt.setOnClickListener(new Listener1());
history_bt.setOnClickListener(new Listener2());
}
class Listener1 implements View.OnClickListener{
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
}
class Listener2 implements View.OnClickListener{
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
}
staic
- 變量、方法
- 靜態代碼塊:靜態代碼塊—>非靜態代碼塊—>構造方法。
- 靜態內部類
- 靜態導包(1.5新特性)
靜態代碼塊和非靜態代碼塊
public class Dog {
{
System.out.println("這裏是非靜態代碼塊");
}
static {
System.out.println("這裏是靜態代碼塊");
}
public Dog(){
System.out.println("這裏是構造函數");
}
}
結果爲:
I/O流
基類:
InputStream/Reader: 所有的輸入流的基類
OutputStream/Writer: 所有輸出流的基類
BIO、NIO、AIO
- BIO: 阻塞IO
- NIO: 同步非阻塞IO
- AIO: 異步非阻塞的IO
淺拷貝和深拷貝
Collection
- 排序
- 查找、替換
- 同步控制(可以用JUC包併發集合替代)
排序操作
public class Test {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(4);
list.add(3);
list.add(2);
list.add(1);
System.out.println("開始序列:"+list);
Collections.reverse(list);
System.out.println("翻轉後:"+list);
Collections.shuffle(list);
System.out.println("隨機後:"+list);
Collections.sort(list);
System.out.println("排序後:"+list);
Collections.swap(list,0,3);
System.out.println("交換第1和3個後:"+list);
//定製sort
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return -o1.compareTo(o2);
}
});
System.out.println("定製sort後:"+list);
}
查找、替換
System.out.println(list+" 二分查找3:"+Collections.binarySearch(list,3));
System.out.println("最大元素:"+Collections.max(list));
System.out.println("3出現次數:"+Collections.frequency(list,3));
ArrayList<Integer> list1 = new ArrayList<>();
list1.add(3);
list1.add(2);
System.out.println("3,2出現在哪裏:"+Collections.indexOfSubList(list,list1));
結果爲:
Arrays操作
int arr[]={5,4,3,2,1};
Arrays.sort(arr,1,3);
System.out.println("arr排序1到3:"+Arrays.toString(arr));
Arrays.sort(arr);
System.out.println("arr排序後:"+Arrays.toString(arr));
System.out.println(Arrays.toString(arr));
System.out.println("4在位置:"+Arrays.binarySearch(arr,4));
結果爲:
剩下還有:
- 比較 equals
- 填充 fill
- 轉列表 asList
- 轉字符串 toString
- 複製 copyOf
BigDecimal的用處
浮點數之間等值判斷不能使用==來比較,包裝數據類型不能用equals來比較。
BigDecimal a = new BigDecimal("1.0");
BigDecimal b = new BigDecimal("0.9");
BigDecimal c = new BigDecimal("0.8");
BigDecimal x = a.subtract(b);
BigDecimal y = b.subtract(c);
System.out.println("兩結果之間進行對比:"+x.equals(y));
//保留幾位小數n
BigDecimal m = new BigDecimal("1.2223456");
BigDecimal n = m.setScale(3, BigDecimal.ROUND_HALF_DOWN);
System.out.println(m+"保留三位:"+n);
結果顯示爲:
Arrays.asList使用
注意必須傳入對象數組,基本類型不可以。
且底層就是數組。
最重要的是,Arrays.asList() 方法返回的並不是 java.util.ArrayList ,而是 java.util.Arrays 的一個內部類,這個內部類並沒有實現集合的修改方法或者說並沒有重寫這些方法。
Integer arrls[]={8,7,6,5};
List<Integer> list = Arrays.asList(arrls);
System.out.println("使用asList後:"+list.toString());
正確將數組轉化爲ArrayList
簡單方法
new ArrayList<>(Arrays.asList(“a”, “b”, “c”))
java8的steam
不要在 foreach 循環裏進行元素的 remove/add 操作
可以用迭代器的remove方法,否則拋出異常。
fail-fast機制: :多線程操作集合,一線程訪問集合,但檢測到集合被其他線程修改,便會出現情況。java.util包下面的所有的集合類都是fail-fast的,而java.util.concurrent包下面的所有的類都是fail-safe的。
Collection.toArray轉爲數組
list.toArray(new String[0])
這裏只爲指定返回的數組的類型。0是爲節省空間。
泛型限定
public static <T extends Comparable<? super T>> T Min(T[] nums){
T val=nums[0];
for(int i=1;i<nums.length;i++){
if(val.compareTo(nums[i])>0){
val=nums[i];
}
}
return val;
}
其中T extends Number表明上限是Number,也就是T必須是Number的子類。? super T 表明下限是T。
例如Integer是這樣定義的:
public final class Integer extends Number implements Comparable<Integer>
- T表示泛型
- ? 表示不確定的類型,一般用在通配
- Object表示java中所有類的父類,在集合中使用時要格外注意。
- jdk爲了便於理解,用K表示鍵,V表示值,T表示type類型,E表示enum枚舉,其實這四個都只是符號,都是表示泛型名稱。換成其他字母都沒關係,但是都要在之前聲明。
泛型數組(重點)
可重入/不可重入鎖
- 不可重入:線程獲取鎖,再次獲取鎖時,就會被阻塞。
- 可重入: 線程可以進入已經擁有鎖的同步代碼塊。
isLocked | false |
lockedBy | null |
lockedCount | 0 |
進入lock():
thread爲當前線程。
由於while(isLocked && lockedBy != thread),而isLocked爲false,所以不執行while內的wait,而是
isLocked | true |
lockedBy | 當前線程 |
lockedCount | 1 |
接着這個線程再次申請這個鎖,由於滿足lockedBy與當前線程匹配,所以仍不能執行while,而是
isLocked | true |
lockedBy | 當前線程 |
lockedCount | 2 |
如果此時有其它線程執行lock(),那麼就會滿足while的條件,而執行wait(),掛起等待。
總結:如此便實現了一個線程可以重入一個鎖。
樂觀鎖、悲觀鎖
- synchronized是悲觀鎖,這種線程一旦得到鎖,其他需要鎖的線程就掛起。
- CAS是樂觀鎖,每次不加鎖,有衝突就重試。
CAS( Compare And Swap )比較並替換。