Java core 基礎概念
JAVA學習中記錄的一些筆記,不斷更新
目錄
1.識別符號
包名:xxxyyyzzz
類名介面名:XxxYyyZzz
變數名函式名:xxxYyyZzz
常量名:XXX_YYY_ZZZ
2.變數
基本資料型別:資料型,字元型,布林型(棧記憶體)
引用資料型別:類,介面,陣列(棧記憶體引用堆記憶體)
當資料不確定時,且需要對資料進行儲存時,定義變數
3.邏輯運算子
&和&&:
&:無論左邊是true還是false,右邊都運算
&&:當左邊為false時,右邊不運算
|和||
|:兩邊都參與運算
||:當左邊為true時,右邊不運算
4.位運算子(高效運算)
左移<<:乘2的移動位數次冪
右移>>:除2的移動位數次冪
>>:最高位補什麼由原有資料的最高位值而定
如果最高位0,右移後,用0補空位
如果最高位1,右移後,用1補空位
>>>:無論最高位是什麼,右移後,都用0補
異或^:A^B^B=A(加密解密,資料交換)
5.語句
switch:判斷的具體數值不多,且符合byte,short,int,char,String(1.7)型別
if:對區間判斷,對結果為Boolean型別判斷
for:變數有作用域,迴圈增量定義在for中,且只在for中有效,for執行完畢後,該增量在記憶體中消失。for(;;){}-->(無限迴圈)
while,dowhile:運算結果用於迴圈外,while(true){}-->(無限迴圈)
break:跳出,應用於選擇結構和迴圈結構
continue:繼續,應用於迴圈結構,結束本次迴圈繼續下次迴圈
6.函式(方法)
過載(overload):同一個類中,同名且引數個數或引數型別不同,與返回值型別無關。當定義的功能相同,但參與運算的位置內容不同,定義一個函式名稱以表示該功能,通過引數列表的不同來區分多個同名函式。
主函式(main 不是關鍵字):是一個特殊的函式,作為程式入口,可以被JVM呼叫
public static void main(String[] args)args==arguments(n.引數)
public:代表該函式訪問許可權最大
static:代表主函式隨著類的載入就已經存在了
void:主函式沒有具體的返回值
String [] args:函式的引數,引數型別是一個字串陣列,傳入的是new String[0] 空陣列
javac mainDemo
java mainDemo haha hehe heihei
System.out.println(args[0]);--->haha
7.記憶體結構
棧記憶體:用於儲存區域性變數,當資料使用後,所佔空間會自動釋放
堆記憶體:陣列和物件,通過new建立的例項都存放在堆記憶體中,每一個實體都有記憶體地址值,實體中的變數都有預設初始化值,實體不在被使用,會在不確定的時間內被垃圾回收器回收。
[I@xxxxxx:一維陣列,integer型別元素,記憶體地址(雜湊值,十六進位制)
方法區:
本地方法區:
暫存器:
8.陣列
排序:Arrays.sort(arr);
選擇排序:內迴圈結束一次,最值出現在頭角標位上
public static void selectSort(int []arr)
{
for(int x=0;x<arr.length;x++)
{
for(int y=x+1;y<arr.length;y++)
{
if(arr[x]>arr[y])
{
int temp=arr[x];
arr[x]=arr[y];
arr[y]=temp;
}
}
}
}
氣泡排序:
public static void bubbleSort(int []arr)
{
for(int x=0;x<arr.length-1;x++)
{
for(int y=0;y<arr.length-x-1;y++)//-x:讓每一次比較的元素減少 -1:避免角標越界
{
if(arr[y]>arr[y+1])
{
int temp=arr[y];
arr[y]=arr[y+1];
arr[y+1]=temp;
}
}
}
}
9.面向物件
封裝,繼承,多型
具體物件就是java在堆記憶體用new建立實體
屬性就是類中變數,行為就是類中函式(成員變數和成員方法)
類型別變數指向堆記憶體中的物件
成員變數和區域性變數 作用範圍
成員變數作用於整個類中,存放於堆記憶體,因為物件的存在,才在記憶體中存在
區域性變數作用於函式中,或者語句中,存放於棧記憶體中
10.匿名物件
當對物件的方法(非屬性變數,呼叫完即在記憶體中成為垃圾,等待回收)只調用一次時,可簡化為匿名物件
可以將匿名物件作為實際引數進行傳遞
Car c=new Car();
show(c);
show(new Car());
11.訪問控制修飾符
用於控制被修飾變數、方法、類的可見範圍.
public 的訪問級別是最高的,其次是 protected、預設和 private.
成員變數和成員方法可以處於4個訪問級別中的一個:公開、受保護、預設或私有.
存在繼承關係時,父類不可以是 private,因為子類無法繼承
頂層類可以處於公開或預設級別,頂層類不能被 protected 和 private 修飾. (外部類)
區域性變數不能被訪問控制修飾符修飾
private:私有,用於修飾類中成員(成員變數和成員方法),私有隻在本類中有效,物件不能直接訪問,提供get,set方法進行訪問。僅僅是封裝的一種表現形式
預設許可權(不寫default):介於私有和共有之間
public:
protected:
12.建構函式
預設建構函式(系統自帶): 類名(){} 預設建構函式的許可權隨著類的變化而變化
自定義建構函式後,預設建構函式消失
物件一建立,就會呼叫與之對應的建構函式,可以用於給物件進行初始化,只執行一次
構造程式碼塊 {}
作用:給物件進行初始化 物件一建立就執行,而且優先於建構函式執行
構造程式碼塊是給所有物件進行統一初始化(定義不同物件共性的初始化內容)
建構函式是給對應的物件初始化
13.this關鍵字
代表對本類物件的引用
預設被省略
用於區分區域性變數和成員變數同名的情況
代表它所在函式所屬物件的引用
當定義類中功能(方法)時,該函式內部要用到呼叫該函式的物件時,這時用this來表示這個物件
但凡本類功能內部使用了本類物件,都用this表示
this語句:只能用於在建構函式間進行互相呼叫,this語句只能定義在建構函式第一行,因為初始化要先執行
Person()
{
this.name="xixi";
}
Person(String name)
{
this();
this.name=name;
}
Person(String name,int age)
{
this(name);
//this.name=name;
this.age=age;
}
14.static關鍵字
靜態 用於修飾成員(成員變數,成員函式),成員被靜態修飾後,成員不存在於堆記憶體中,而存在於方法區(共享區,資料區),在記憶體中只有一個副本
被修飾的成員:隨著類的載入而載入,優先於物件存在,被所有物件所共享,共享資料 (country=“CN”(類變數))
可以直接被類名呼叫(類名.靜態成員),因為靜態成員存在時,物件可能不存在。
注意事項:靜態方法只能訪問靜態成員,非靜態方法既可以訪問靜態也可以訪問非靜態,
靜態方法中不可以寫this,super關鍵字,主函式是靜態的
利處:對物件的共享資料進行單獨空間儲存,節省空間,沒有必要每個物件都儲存一份。
弊處:生命週期過長,訪問出現侷限性
用處:當物件中出現共享資料(值)時,該資料被靜態修飾,物件特有資料定義成非靜態。
當功能內部沒有訪問到非靜態資料時,該功能可以定義成靜態方法
應用:每一個應用程式中都有共性的功能,可以將這些功能進行抽取,獨立封裝,以便複用。
工具類(ArrayTool等)不需要物件,可將類中方法定義成靜態的,直接通過類名呼叫。因為不需要建立物件,可將建構函式私有化強制不能建立物件。
靜態程式碼塊: static{ 語句 } 隨著類的載入而執行,只執行一次。用於給類進行初始化。
15.物件的初始化過程
class Person
{
private String name="xixi";
private int age;
private static String country="CN";
Person (String name,int age)
{
this.name=name;
this.age=age;
}
{
System.out.println(name+"--"+age);
}
public void setName(String name)
{
this.name=name;
}
public void speak()
{
System.out.println(this.name+"--"+this.age);
}
public static void showcountry()
{
System.out.println("country="+country);
}
}
class PersonDemo
{
public static void main(String []args)
{
Person p=new Person("heihei",10);
}
}
Person p=new Person("heihei",10);
1.因為new用到了Person.class,所以會先找到Person.class檔案並載入到記憶體中(Person p=null 這種情況類不載入(new時會用到建構函式))
2.執行該類中的static程式碼塊,如果有的話,給Person.class進行初始化。
3.在堆記憶體中開闢空間,分配記憶體地址。
4.在堆記憶體中建立物件的特有屬性,並進行預設初始化。
5.對屬性進行顯示初始化。
6.對物件進行構造程式碼塊初始化。
7.對物件進行對應的建構函式初始化。
8.將記憶體地址賦給棧記憶體中的p變數。
16.繼承
特性:單繼承(多繼承安全隱患),支援多層繼承
聚集 :has a
聚合:球隊球員
組合:人體器官
提高程式碼的複用性,讓類與類之間產生了關係,有了這個關係,才有了多型的特性。所屬關係 :is a
如何使用一個繼承體系中的功能:先查閱體系父類的描述,因為父類中定義的是該體系中共性功能,通過了解共性功能。就可以知道該體系的基本功能。在具體呼叫時,要建立最子類的物件,因為有可能父類不能建立物件(抽象類),建立子類物件可以使用更多功能。
當子類繼承父類,沿襲了父類的功能,到子類中,但是子類雖具備該功能,但是功能的內容卻和父類不一致,這時,沒有必要定義新功能,而是使用覆蓋,保留父類的功能定義,並重寫功能內容。
子類覆蓋父類,必須保證子類許可權大於等於父類許可權,才可以覆蓋,否則編譯失敗。(方法非屬性)靜態只能覆蓋靜態。
如果子類和父類中有同名屬性,父類引用指向子類物件的時候,通過父類引用訪問那個同名屬性時,訪問的是父類中的那個,不是子類中的那個,因為父類引用是看不到子類中的屬性的,這和方法不同,父類引用呼叫子類方法時有個優先順序的問題,this優先於super,即,如果子類中重寫了父類的方法,那麼呼叫的就是子類中的,如果沒有重寫,就呼叫的是父類中的。
public class tt
{
public static void main(String[] args) throws Exception{
A b=new B(); //父類引用指向子類物件
b.show();//輸出bbbb
System.out.print(b.num);//輸出111
int x=b.getnum();
System.out.print(x);//輸出333
b.ss();//輸出AAAA
}
}
class A
{
public int num=111;
public void show()
{
System.out.print("aaaa");
}
public int getnum() {
return num;
}
public void ss()
{
System.out.print("AAAA");
}
}
class B extends A
{
public int num=333;
public int getnum()
{
return num;
}
public void show()
{
System.out.print("bbbb");
}
}
17.super關鍵字
代表對父類物件的引用
在對子類物件進行初始化時,父類的建構函式也會執行,那是因為子類的建構函式預設第一行有一條隱式語句 super();
super():會訪問父類中空引數的建構函式,而且子類中所有的建構函式預設第一行都是super();
因為父類中的資料子類可以直接獲取,所以子類物件在建立時,需要先檢視父類時如何對這些資料進行初始化的。所以子類在物件初始化時,要先訪問一下父類中的建構函式。如果要訪問父類中指定的建構函式,可以通過手動定義super語句的方法來指定。當然,子類的建構函式第一行也可以手動指定this語句來訪問本類中的建構函式,子類中至少會有一個建構函式會訪問父類中的建構函式。
18.final關鍵字
final可以修飾類,方法,變數。
final修飾的類不可以被繼承。
final修飾的方法不可以被覆蓋。
final修飾的變數是一個常量,只能被賦值一次。
內部類只能訪問被final修飾的區域性變數。
19.abstract關鍵字
當多個類中出現相同功能,但是功能主體不同。這時可以進行向上抽取,這時,只抽取功能定義,而不抽取功能主體。
抽象類的特點:抽象方法一定在抽象類中,抽象方法和抽象類都必須被abstract關鍵字修飾,抽象類不可以用new建立物件,因為呼叫抽象方法沒意義。抽象類中的方法要被使用必須由子類複寫其所有的抽象方法後,建立子類物件呼叫。如果子類只覆蓋了部分抽象方法,那麼該子類還是一個抽象類。
抽象類中可以不定義抽象方法,這樣做僅僅是不讓該類建立物件。
20.介面
可以認為是一個特殊的抽象類,當抽象類中的方法都是抽象的,那麼該類可以通過介面的形式來表示
不可以建立物件,因為有抽象方法,需要被子類實現,子類對介面中的抽象方法全都覆蓋後,子類才可以例項化,否則子類是一個抽象類。
一個類可以實現多個介面也是對多繼承不支援的轉換形式
class用於定義類
interface用於定義介面
介面定義時,格式特點:
介面中常見定義:常量,抽象方法
介面中的成員都有固定修飾符(自動+):常量:public static final
方法:public abstract
介面中的成員都是public
類與類 繼承 extends
類與介面 實現 implements
介面與介面 繼承 extends(介面可以多繼承)
21.多型
可以理解為事物存在的多種體現形態
貓 x=new 貓();
動物 x=new 貓();//型別提升,向上轉型
體現:父類引用指向了自己的子類物件,父類引用也可以接收自己的子類物件
前提:類與類之間必須有關係,要麼繼承,要麼實現
好處:提高程式的擴充套件性
弊端:只能使用父類的引用訪問父類中的成員。
如果子類和父類中有同名屬性,父類引用指向子類物件的時候,通過父類引用訪問那個同名屬性時,訪問的是父類中的那個,不是子類中的那個,因為父類引用是看不到子類中的屬性的,這和方法不同,父類引用呼叫子類方法時有個優先順序的問題,this優先於super,即,如果子類中重寫了父類的方法,那麼呼叫的就是子類中的,如果沒有重寫,就呼叫的是父類中的。
//如果想要呼叫子類的特有方法,就強制將父類的引用,轉成子類型別
Animal a=new Cat();//向上轉型
a.eat();
Cat c=(Cat)a;//向下轉型
c.catchMouse();
//能轉換的是父類引用指向自己的子類物件時,該引用可以被提升,也可以被強制轉換
//多型自始至終都是子類物件在做著變化
Animal a=new Animal();
Cat c=(Cat)a;//這是不允許的
a instanceof Cat//判斷a是否是Cat型別(判斷所屬型別)
在多型中成員函式(非靜態)的特點:
在編譯時期,參閱引用型變數所屬的類中是否有呼叫的方法,如果有,編譯通過,否則編譯失敗
在執行時期,參閱物件所屬的類中是否有呼叫的方法
簡單總結:非靜態成員函式在多型呼叫時,編譯看左邊,執行看右邊
靜態成員函式,無論編譯和執行,都參考左邊
成員變數,無論編譯和執行,都參考左邊(引用型變數所屬的類)
22.內部類
定義原則:當描述事物時,事物的內部還有事物,該事物用內部類來描述。因為內部事物在使用外部事物的內容。
內部類可以直接訪問外部類中的成員,包括私有(因為內部類有預設引用 外部類.this)
外部類要訪問內部類,必須建立內部類物件
其他類直接訪問內部類: Outer.Inner in= new Outer().new Inner();
外部類與內部類出現同名變數時,內部類想要訪問外部類變數:Outer.this.xxx;
內部類在成員位置上,就可以被成員修飾符所修飾
內部類定義在區域性時,不可以被成員修飾符修飾
訪問區域性變數時,區域性變數必須被final修飾
private :將內部類在外部類中進行封裝
static:內部類具有靜態特性(靜態內部類),只能直接訪問外部類中的靜態成員
當內部類中定義了靜態成員,該內部類必須是靜態的
當外部類中的靜態方法訪問內部類時,內部類也必須是靜態的
其他類訪問靜態內部類的非靜態成員 new Outer.Inner().function();
其他類訪問靜態內部類的靜態成員 Outer.Inner().function();
23.匿名內部類
匿名內部類其實就是內部類的簡寫格式。是一個匿名子類物件
前提:內部類必須是繼承一個類或者實現介面
匿名內部類中定義的方法最好不要超過三個
abstract class AbsDemo
{
abstract void show();
}
class Outer
{
int x=3;
/*
class Inner extends AbsDemo
{
void show()
{
System.out.println(x);
}
}
*/
public void function
{
//new Inner().show();
new AbsDemo()//建立的是AbsDemo的子類,因為show方法被重寫了
{
void show()
{
System.out.println(x);
}
}.show();
}
}
interface Inter
{
void method();
}
class Test
{
public static Inter function()//1
{
return new Inter()
{
public void method()
{
System.out.println("haha");
}
};
}
}
class TestDemo
{
public static void main(String []args)
{
Test.function().method();//1
show(new Inter()
{
public void method()
{
System.out.println("haha");
}
});//2
}
public static void show(Inter in)//2
{
in.method();
}
}
24.異常
程式在執行時出現的不正常情況
異常由來:問題也是現實生活中一個具體的事物,也可以通過JAVA的類的形式進行描述,並封裝成物件
其實就是java對不正常情況進行描述後的物件體現
問題劃分:嚴重的 java通過Error類進行描述(一般不編寫針對性的程式碼對其進行處理)
非嚴重的 java通過Exception類進行描述(可以使用針對性的處理方式進行處理)
向上抽取 父類 Throwable
異常的處理:
try{ 需要被檢測的程式碼 }
catch( 異常類 變數 ){ 處理異常的程式碼(處理方式) } (Exception e = new XXXException())
finally{ 一定會執行的語句 通常用於關閉資源(IO流 SQL連線) }
宣告異常:throws Exception 必須有try catch迴應,否則編譯失敗,除非一直拋,直到拋給JVM處理。
宣告異常時,簡易宣告更具體的異常 如除零 ArithmeticException
對方宣告幾個異常,就對應有幾個catch塊,不要定義多於的catch塊。
如果多個catch塊中的異常出現繼承關係,父類異常catch塊放在最下面。
建議在進行catch處理時,一定要定義具體處理方式,不要簡單定義一句e.printStackTrace語句。
自定義異常
因為專案中會出現特有的問題。而這些問題並未被java所描述並封裝成物件。 所以對於這些特有的問題可以按照java的對問題封裝的思想,將特有的問題,進行自定義的異常封裝。
當在函式內部出現了throw丟擲異常物件,那麼就必須要給對應的處理動作,要麼在內部try catch 要麼在函式上宣告讓呼叫者處理。
一般情況下,函式內出現異常,函式上需要宣告。
如何定義異常資訊:因為父類已經把異常資訊的操作都完成了,所以子類只要在構造時,把異常資訊傳遞給父類通過super語句。那麼就可以直接通過getMessage方法獲取自定義的異常資訊。
自定義異常,必須是自定義類繼承Exception
異常體系有一個特點,因為異常類和異常物件都被丟擲,他們都具備可拋性,這個可拋性是throwable這個體系中的獨有特點。
只有這個體系中的類和物件才可以被throw和throws操作。
throw和throws的區別:
throws使用在函式上 throw使用在函式內
throws後面跟的是異常類,可以跟多個,用逗號隔開 throw後面跟的是異常物件
class FuShuException extends Exception
{
private int value;
FuShuException()
{
super();
}
FuShuException(String message,int value)
{
super(message);
this.value=value;
}
public int getValue()
{
return value;
}
}
class Demo
{
int div(int a,int b)throws FuShuException
{
if(b<0)
throw new FuShuException("出現了除負數異常!!!",b);//手動通過throw關鍵字丟擲自定義異常
return a/b;
}
}
class Test
{
public static void main(String []args)
{
Demo d=new Demo();
try
{
int x=d.div(4,-9);
System.out.println(x);
}
catch(FuShuException e)
{
System.out.println(e.toString());
System.out.println("錯誤的負數是"+e.getValue());
}
}
}
特殊異常:RuntimeException
Exception中有一個特殊的子類異常RuntimeException執行時異常
如果在函式內中丟擲異常,函式可以不用宣告,編譯一樣通過。
如果在函式上聲明瞭該異常,呼叫者可以不進行處理,編譯一樣通過。
之所以不用函式宣告,是因為不需要讓呼叫者處理,當該異常發生,希望程式停止,因為在執行時,出現了無法繼續運算的情況,希望停止程式後,對程式碼進行修正。
自定義異常時,如果該異常的發生,無法在繼續進行運算,就讓自定義異常繼承RuntimeException.
異常分兩種
編譯時被檢測的異常
編譯時不被檢測的異常(RuntimeException及其子類)
異常在子父類覆蓋中的體現:
1 子類在覆蓋父類方法時,如果父類的方法丟擲異常,那麼子類的覆蓋方法,只能丟擲父類的異常或者該異常的子類,或者不拋(自己捕獲異常並解決)
2 如果父類方法丟擲多個異常,那麼子類在覆蓋該方法時,只能丟擲父類異常的子集
3 如果父類或者介面的方法中沒有異常丟擲,那麼子類在覆蓋方法時,也不可以丟擲異常(如果子類方法發生了異常,就必須進行try處理,絕對不能拋)
總結
Ps:截圖為畢向東老師Java基礎視訊。
25.包
對類檔案進行分類管理,給類提供多層名稱空間,寫在程式檔案的第一行,類名的全稱是 包名.類名,包也是一種封裝形式。
編譯:javac -d . PakeageDemo.java(-d 引數 包資料夾地址 (.為當前地址))
執行:java pack.PakeageDemo
總結:包與包之間進行訪問,被訪問的包中的類以及類中的成員,需要被public修飾
不同包中的子類還可以直接訪問父類中被protected許可權修飾的成員
import:為了簡化類名的書寫,使用此關鍵字
//如果不import的話 pack.packzi.DemoB a=new pack.packzi.DemoB();
建議不寫萬用字元* 需要使用哪個類。就匯入哪個。
c:\myclass
c:\myclass\pack\DemoA.class
c:\myclass\pack\packzi\DemoB.class
import pack.*; 匯入的是pack中的所有類,不包括packzi中的類
import pack.packzi.*; 匯入的是packzi中的所有類
定包名不要重複,可以使用url來定義
import cn.itcast.demo
26.多執行緒
一個程式至少有一個程序,一個程序至少有一個執行緒
程序:是一個正在執行中的程式。每一個程序都有一個執行順序,該順序是一個執行路徑,或者叫一個控制單元。
執行緒:就是程序中的一個獨立的控制單元,執行緒在控制著程序的執行。
一個程序中至少有一個執行緒。
Javac 編譯時 會啟動javac.exe 編譯完成後關閉
Java VM 啟動的時候會有一個程序java.exe
該程序至少有一個執行緒負責java程式的執行,而且這個執行緒執行的程式碼存在於main方法中,該執行緒稱之為主執行緒。
JVM不止啟動一個執行緒,還有負責垃圾回收機制的執行緒。
建立執行緒的第一種方式:繼承Thread類
定義類繼承Thread 重寫Thread類中的run方法,呼叫執行緒的start方法(start方法啟動執行緒並呼叫run方法)。
class Demo extends Thread
{
Demo(String name)
{
super(name);//自定義執行緒名稱
}
public void run()
{
System.out.print(this.getName());
// System.out.print(Thread.currentThread().getName()); Thread.currentThread() 獲取當前執行緒的引用 建議使用這種方法
}
}
main()
{
Demo d=new Demo("xixi");//建立執行緒
d.start();//啟動執行緒 並呼叫run方法 則d這個執行緒和主執行緒就在“同時”執行(併發),出現隨機性,CPU執行誰,誰執行。
//d.run(); 如果直接呼叫run方法,而沒有啟動執行緒,run()中的程式碼執行完畢後主函式才會繼續執行。
}
執行緒有預設名字 格式:Thread-編號 編號從0開始。
自定義執行緒名字 :建構函式或者setName()方法
多執行緒具有隨機性,誰搶到誰執行。
執行緒的幾種狀態:
建立執行緒的第二種方式:實現Runnable介面
定義類實現Runnable介面,覆蓋Runnable介面中的run方法,通過Thread類建立執行緒物件,將Runnable介面的子類物件作為
實際引數傳遞給Thread類的建構函式,呼叫Thread類的start方法開啟執行緒並呼叫Runnable介面子類的run方法。
繼承方式和實現方式:建議使用實現方式,避免了單繼承的侷限性。
區別:繼承---執行緒程式碼存放在Thread子類run方法中。
實現---執行緒程式碼存放在介面子類run方法中。
多執行緒安全問題: 當多條語句在操作同一個執行緒共享資料時,一個執行緒對多條語句只執行了一部分,還沒有執行完,另一個執行緒參與進來執行時,導致共享資料的錯誤。
Java解決多執行緒的安全問題的方法:同步程式碼塊/同步函式
Object obj=new Object();
synchronized(物件){}
哪些程式碼需要放進同步程式碼塊中:
明確哪些程式碼是多執行緒執行程式碼
明確共享資料
明確多執行緒執行程式碼中哪些語句是操作共享資料的
同步函式使用的鎖是this
靜態同步函式,使用的鎖是該方法所在類的位元組碼檔案物件 類名.class(靜態方法中不可以定義this 靜態進記憶體 記憶體中沒有本類物件 但是一定有該類對應的位元組碼檔案物件 所以該物件的型別是Class)
同步程式碼塊
同步函式
同步函式
物件如同鎖,持有鎖的執行緒可以在同步中執行,沒有持有鎖的執行緒即使獲取了cpu的執行權,也進不去,因為沒有獲取鎖
同步的前提:必須要有兩個或者兩個以上的執行緒,必須是多個執行緒使用一個鎖
雖然同步程式碼塊解決了多執行緒的安全問題,但多個執行緒都需要判斷鎖,較為消耗資源。
死鎖:同步中含有同步
賣票:
public class TicketSale {
public static void main(String[] args) {
Ticket t1=new Ticket();
Ticket t2=new Ticket();
Ticket t3=new Ticket();
Ticket t4=new Ticket();
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class Ticket extends Thread
{
private static int tick=100;
public void run()
{
while(tick>0)
{
System.out.println(currentThread().getName()+"----"+tick--);
}
}
}
public class TicketSale {
public static void main(String[] args) {
Ticket t=new Ticket();
new Thread(t).start();
new Thread(t).start();
new Thread(t).start();
new Thread(t).start();
}
}
class Ticket implements Runnable
{
private int tick=100;
Object obj=new Object();
public void run()
{
while(true)
{
synchronized(obj)
{
if(tick>0)
{
System.out.println(Thread.currentThread().getName()+"----"+tick--);
}
}
}
}
}
多執行緒通訊: 多個執行緒在操作同一個資源,但是操作的動作不同
wait() nitify() notifyAll()
都是用在同步中,因為要對持有監視器(鎖)的執行緒操作。只有同步才具有鎖。
為什麼這些方法定義在Object類:因為這些方法在操作同步中執行緒時,都必須要標識他們所操作執行緒只有的鎖,只有同一個鎖上的被等待執行緒,才可以被同一個鎖上的notify喚醒,不可以對不同鎖中的執行緒進行喚醒。
而鎖可以是任意物件,所以可以被任意物件呼叫的方法定義在Object類中
優化:
生產者消費者:
多個生產者多個消費者
1.在判斷flag時,用While不用if(每次被喚醒應重新判斷flag 可能會導致生產兩個 消費一個等不匹配情況,)
2.應使用notifyAll();(用notify可能導致所有執行緒都wait()。)
JDK1.5 提供了多執行緒升級方案
將同步Synchronized替換成顯式Lock操作,將Object中的wait,notify,notifyALL替換成了Condition物件,該物件可以Lock鎖進行獲取,可以實現本方執行緒只喚醒對方執行緒的操作。
相關介面:Condition Lock
執行緒停止:
守護執行緒(後臺執行緒):噹噹前執行緒都為守護執行緒時,自動結束。
Join:等待執行緒結束
27.String
字串特點:一旦被初始化,就不可以被改變。存在於常量池。
String使用private final char value[ ]實現字串的儲存,也就是說String建立物件之後不能夠再次修改此物件中儲存的字串內容
String s="abc";//s1是一個類型別變數,"abc"是一個物件
s="123"; //此時"abc"這個物件的內容並沒有改變,只是s這個引用指向了另一個物件,即"123"
String類中重寫了equals方法用於比較兩個字串的內容是否相等。(Java中也有其他類對equals進行了重寫)
一般情況 | String類重寫 | |
== | 比較記憶體地址 | ------ |
equals | 比較記憶體地址 | 比較內容 |
public class sss {
public static void main(String []args)
{
String s1="aaa";
String s2="aaa";
String s3=new String("aaa");
//s1和s3的區別
s1在記憶體中有一個物件
s2在記憶體中有兩個物件
System.out.println(s1==s2);//true 指向的是同一個物件
System.out.println(s1==s3); //false 不是一個物件 記憶體地址不同
System.out.println(s1.equals(s3));//true 不是一個物件,但內容相同
}
}
字串常用操作方法:
1.字串去頭尾空格:
2.字串反轉(或部分反轉):
3.字串個數
4.獲取最大相同字串
StringBuffer:
StringBuilder:單執行緒使用StringBuilder可提高效率
28.包裝類
自動裝箱拆箱:
29.集合
集合用來儲存物件(記憶體地址),長度是可變的,可以儲存不同型別物件。
Collection---List Set
List--- ArrayList LinkedList Vector
Set--- HashSet TreeSet
Iterator介面 迭代器:
30.List集合
元素是有序的,可以重複,集合有角標。
ArrayList:
LinkedList:
封裝LinkedList到自己的類中:
佇列/堆疊
Vector:
31.Set集合
元素無序(存入和取出的順序不一定一致),且元素不能重複。
HashSet:
底層資料結構為雜湊表,集合中元素的存的順序為元素雜湊值大小順序。如果雜湊值相同,在判斷是否是同一物件(equals()),不是則順延存入。
例子:
TreeSet
可以對Set集合中的元素進行排序,按ASCII順序。 底層資料結構為二叉樹
(1)物件類中自帶比較
存物件時,需要實現Comparable介面中的唯一一個函式 compareTo()方法,並定義返回的int型,
返回負數,零,正數 分別代表 曉宇 等於 大於。等於時物件相等,不存入。主要條件相同時,判斷次要條件。
如果想要實現按存入順序取出的話,compareTo方法就一直返回正數。取出時預設從小到大取。
(2)TreeSet建構函式中傳入比較器
定義自定義比較器類實現Comparator
物件和容器都有排序時,以容器的排序為主。
32.集合泛型
集合中使用泛型來約束集合中要儲存的類型別
當類中要操作的引用資料型別不確定的時候,定義泛型類。(靜態方法不能訪問類上定義的型別,因為靜態方法存在時,類還不存在)
方法也可以定義泛型。泛型放在返回值前面
介面也可以定義泛型
泛型限定
33.Map
HashMap
keySet:取出所有鍵存到Set中
entrySet:取出每一條資料對映關係存到Set中
相關推薦
Java core 基礎概念
JAVA學習中記錄的一些筆記,不斷更新 目錄 1.識別符號 2.變數 5.語句 8.陣列 16.繼承 20.介面 21.多型 24.異常 25.包 29.集合
[18/11/7] Java的基礎概念
java語言的優勢是跨平臺 ,計算機界的英語,是IT行業的第一大語言 特點是多執行緒 分散式 健壯性 面向物件 java和JavaScript的關係 雷鋒和雷峰塔的關係 或卡巴斯基
Java註解基礎概念總結
註解的概念 註解(Annotation),也叫元資料(Metadata),是Java5的新特性,JDK5引入了Metadata很容易的就能夠呼叫Annotations。註解與類、介面、列舉在同一個層次,並可以應用於包、型別、構造方法、方法、成員變數、引數、本地變數的宣告中,用來對這些元素進行說明註釋。 註
RabbitMQ訊息佇列入門篇(環境配置+Java例項+基礎概念)
一、訊息佇列使用場景或者其好處 訊息佇列一般是在專案中,將一些無需即時返回且耗時的操作提取出來,進行了非同步處理,而這種非同步處理的方式大大的節省了伺服器的請求響應時間,從而提高了系統的吞吐量。 在專案啟動之初來預測將來專案會碰到什麼需求,是極其困難的。訊息
Java面試基礎概念總結
前段時間由於忙於修改論文,就好久沒更新部落格,現在準備重新開始記錄自己的屌絲人生。哈哈 面向物件軟體開發的優點有哪些? 答:開發模組化,更易維護和修改;程式碼之間可以複用;增強程式碼的可靠性、靈活
JAVA一些基礎概念
JRE為Java Runtime Environment的簡稱,Java Runtime Environment(包括Java Plug-in)是Sun的產品,包括兩部分:Java Runtime Environment和Java Plug-in。JavaRuntimeEnvironment(JRE)是可
java 基礎概念 -- 數組與內存控制
nbsp 堆內存 數組元素 art pan popu ace article pac 問題1: Java在聲明數組的過程中,是怎樣分配內存的? 在棧內存中 建一個數組變量,再在堆內存中 建一個 數組對象。至於詳細的內存分配細節,還得看 該初始化是 數組動態初始化 還是
粵嵌java培訓第一天筆記-java基礎概念
ont 類型 運算符 按位或 次循環 規則 是否 支持 har 一、二進制數 1、最高位為0,表示正數;最高位為1,表示負數。 2、相應的負數與正數之間進行轉換方式:通過補碼方式進行轉換,即:取反再加1。 例如:0000 0001 表示 +1;通過對 000
Java基礎概念收集
安全性 當前 javaweb query fig 響應 請求 私有 引用 Javaweb階段 Ajax你以前用過麽?簡單介紹一下 AJAX = 異步 JavaScript 和 XML。 AJAX 是一種用於創建快速動態網頁的技術。 通過在後臺與服務器進行少量數據交換,AJA
java基礎概念
ipc javaee 目錄 基本數據類型 字符串 註釋 單行 公司 開發工具 一、Java語言從何而來?發展平臺版本 Java語言最初是屬於SUN公司的產品,始於1994年 Java語言之父:詹姆斯高斯林 Java語言平臺版本: JavaSE:
Java反射之基礎概念
ide 包名 void java 類名 super 運行 生成 over 0.實例準備 package com.blueStarWei.invoke; public class Student { private String name; pu
菠菜源碼搭建與java基礎概念
意義 硬件 protect str 數值類型 cto 尋找 nta java基礎 1.java jvm的功能:通過 ClassLoader 尋找和裝載 class 文件?? ??? ??? ?? 解釋字節碼成為指令並執行,提供 class 文件的運行環境?? ??? ???
h--5--菠菜源碼下載java基礎概念
應用程序 虛擬 clas 不同 world 空間 ase 即時編譯 rac 1.第一個應用程序:Hello World!package my.xkyy.lsc;public class HelloWorld {public static void main(String[]
Java 多執行緒設計模式之基礎概念
順序、併發與並行 順序 用於表示多個操作“依次處理”。比如把十個操作交給一個人來處理時,這個人要一個一個地按順序來處理 並行 用於標識多個操作“同時處理”。比如十個操作分給兩個人處理時,這兩個人就會並行來處理。 併發 相對於順序和並行來說比較抽象,用於表示“將一個
Java面試題:面向物件,類載入器,JDBC, Spring 基礎概念
1. 為什麼說Java是一門平臺無關語言? 平臺無關實際的含義是“一次編寫到處執行”。Java 能夠做到是因為它的位元組碼(byte code)可以執行在任何作業系統上,與底層系統無關。 2. 為什麼 Java 不是100%面向物件? Java
Java併發程式設計1.1—基礎概念
併發程式設計1.1—基礎概念 1.CPU核心數和執行緒數的關係和區別 簡單的說: CPU核心數:執行緒數=1:1 ;使用了超執行緒技術後—> 1:2。 詳細解釋: CPU核心數指物理上,也就是硬體上存在著幾個核心。比如,雙核就是包括2個相對獨立的CPU核
Java NIO筆記之IO基礎概念
1.緩衝區 緩衝區是所有IO的基礎,”輸入/輸出”就是將資料移進或移除緩衝區。程序IO操作的執行也是向作業系統傳送請求,讓它要麼將緩衝區的資料排幹(寫),要麼將緩衝區的填滿資料(讀)。 圖 1-1 簡單描述了資料從外部磁碟向執行中的程序的記憶體區
java基礎概念finalize、final和finaly的區別
final: 1.應用於基本型別變數時,該變數的值無法改變 2.應用於引用變數時,該引用變數不能只想堆上的任何其他物件 3.應用於方法時,該方法不能被重寫 4.應用於類時,該類不能被繼承finally
Java基礎概念之JSE JME JEE JDK JRE JVM
JSE. JME,JEE,JDK,JRE SE:stands for "Standard Edition" EE:stands for "Enterprise Edition" JDK: stands for “Java Development Kit" JRE: stan
黑馬程式設計師--Java學習日記之基礎知識(思維導圖&基礎概念)
------- android培訓、java培訓、期待與您交流! ---------- 什麼是常量 在程式執行的過程中其值不可以發生改變 Java中常量的分類