Unsupported major.minor version 51.0解決辦法
具體步驟
解決:項(xiàng)目------>右鍵------>屬性------>JavaCompiler------>Compiler ComplianceLevel------>選擇你使用的JDK版本------>應(yīng)用
myeclipse出現(xiàn)Could not find the main class原因分析
做如下檢查:
編譯環(huán)境檢查 window->preferences->installed JREs
編譯級(jí)別檢查 右擊工程名->properties->java compiler
編譯路徑檢查 右擊工程名->build path->coufiguration build path
執(zhí)行clean???? project->clean
運(yùn)行環(huán)境大于等于編譯器版本
用JAVA寫一個(gè)單例類:
餓漢式單例:
public class Singleton{
? ? ? ? ?private Singleton(){
? ? ? ? ?private static Singleton instance = new Singleton();
? ? ? ? ?public static ?Singleton getInstance(){
? ? ? ? ? ? ? ? ? return instance;
? ? ? ? ? ? ? ? }
? ? ? ? ? ?}
}
懶漢式單例:
public ?class Singleton{
? ? ? ? private static Singleton instance = null;
? ? ? ? private Singleton(){}
? ? ? ? public static synchronized Singleton getInstance(){
? ? ? ? ? ? ? ? ? if(instance == null) {
? ? ? ? ? ? ? ? ? ? ? ? ?instance = new Singleton();
? ? ? ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ? return instance;
? ? ? ? ? ? ? }
? ? ? ? }
注意:實(shí)現(xiàn)一個(gè)單例有兩點(diǎn)注意事項(xiàng),(1)將構(gòu)造器私有,不允許外界通過構(gòu)造器創(chuàng)建對(duì)象;(2)通過公開的靜態(tài)方法向外界返回類的唯一實(shí)例。
spring的IoC容器可以為普通的類創(chuàng)建單例,它是怎么做到的呢?
DAO設(shè)計(jì)模式:
DAO(Data Access Object)【數(shù)據(jù)訪問對(duì)象】是一個(gè)為數(shù)據(jù)庫或者其他持久化機(jī)制提供了抽象接口的對(duì)象,在不暴露底層持久化方案實(shí)現(xiàn)細(xì)節(jié)的前提下提供了各種數(shù)據(jù)的訪問操作。在實(shí)際的開發(fā)中,應(yīng)該將所有對(duì)數(shù)據(jù)源的訪問操作進(jìn)行抽象化后封裝在一個(gè)公共API中。用程序設(shè)計(jì)語言來說,就是建立一個(gè)接口,接口中定義了此應(yīng)用程序中將會(huì)用到的所有事務(wù)方法。在這個(gè)應(yīng)用程序中,當(dāng)需要和數(shù)據(jù)源進(jìn)行交互的時(shí)候則使用這個(gè)接口,并且編寫一個(gè)單獨(dú)的類來實(shí)現(xiàn)這個(gè)接口,在邏輯上該類對(duì)應(yīng)一個(gè)特定的數(shù)據(jù)存儲(chǔ)。DAO模式實(shí)際上包含了兩個(gè)模式,一是Data Accessor(數(shù)據(jù)訪問器),二是Data Object(數(shù)據(jù)對(duì)象),前者要解決如何訪問數(shù)據(jù)的問題,而后者要解決的是如何用對(duì)象封裝數(shù)據(jù)。
DAO 模式被用來分離低層次數(shù)據(jù)訪問和高級(jí)業(yè)務(wù)邏輯操作
DAO模式中包含的元素:
1.Data Access Object Interface )— 定義了一個(gè)model類上標(biāo)準(zhǔn)的操作方法的接口
2.Data? Access Object concrete class — 實(shí)現(xiàn)了上面接口的類。這個(gè)類負(fù)責(zé)從數(shù)據(jù)存儲(chǔ)區(qū)(數(shù)據(jù)庫、xml)中取得數(shù)據(jù)
3.Model? Object or Value Object? — 這是一個(gè)簡單地POJO(plain OldJavaObject)包含了getter和setter方法。由DAO類進(jìn)行存取
實(shí)現(xiàn):
創(chuàng)建一個(gè)Student類代表了Model或value對(duì)象。StudentDao是一個(gè)Dao接口。StudentDaoImpl是一個(gè)實(shí)現(xiàn)StudentDao的類。

public interface StudentDao{
? ? ? ? ? ?public List<Student> get AllStudents();
? ? ? ? ? ?public Student ?getStudent(int ?id);
? ? ? ? ? ?public void updateStudent(Student student);
? ? ? ? ? ?public void deleteStudent(Student student);
}
選擇排序:
public ?static void selectSort (int [ ] arr){
?for(int ?x = 0; x <arr.length-1;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 main(String[] args){
? ? ? ?int ?[ ] arr = [1,5,4,2,9,6];
? ? ? ? printArray(arr);
? ? ? ? selectSort(arr);
? ? ? ? printArray(arr)
}
public static void printArray( int [ ] arr){
? ? ? ? ? ? for(int x = 0; x<arr.length;x++){
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?if(x!=arr.length-1){
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.println(arr[x]+",");
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? else{
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.println(arr[x]);
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ?}
}
冒泡排序:相鄰的兩個(gè)元素進(jìn)行比較,如果符合條件就進(jìn)行換位
public static ?void bubleSort(int ?[ ] arr){
? ? ? ? for(int ?x = 0 ; x < arr.length -1 ; x ++){
? ? ? ? ? ? ? ? for(int ?y = 0 ; y < arr.length -x -1 ; y++){
? ? ? ? ? ? ? ? ? ? ? ? if( arr[y] > arr[y+1]){
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int temp = arr[y];
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?arr[y] = arr[y+1];
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? arr[y+1] = temp;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ? ? ? ?}
? ? ? ? ? ?}
}
//-x:讓每一次比比較的元素減少;-1:避免角標(biāo)越界
public static void printArray( int [ ] arr){
? ? ? ? for(int x = 0; x<arr.length;x++){
? ? ? ? ? ? ? ? ? ?if(x!=arr.length-1){
? ? ? ? ? ? ? ? ? ? ? System.out.println(arr[x]+",");
? ? ? ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ? else{
? ? ? ? ? ? ? ? ? System.out.println(arr[x]);
? ? ? ? ? ? ? ? }
? ? ? ? ? ?}
? ?}
public static void main(String[] args){
? ? ? ?int ?[ ] arr = [1,5,4,2,9,6];
? ? ? ? printArray(arr);
? ? ? ? ? bubleSort(arr);
? ? ? ? ?printArray(arr)
? ?}
無論什么排序,都需要對(duì)滿足條件的位置進(jìn)行置換,所以可以把這部分相同的代碼提取出來,單獨(dú)封裝成一個(gè)函數(shù)
public static void swap( int [] arr ,int a, int b){
? ? ?int temp = arr[a];
? ? ?arr[a] = arr [b] ;
? ? ? arr[b] = temp;
? }
折半查找:提高效率,但是必須要保證該數(shù)組是有序的數(shù)組
public static int halfsearch( int [ ] arr,int key ){
? ? ? ? ? ? int max,min,mid;
? ? ? ? ? ? min = 0;
? ? ? ? ? ? max = arr.length - 1;
? ? ? ? ? ? mid = (min + max)/2;
? ? ? ? ? ? while(key!=arr[mid]){
? ? ? ? ? ? ? if(key>arr[mid]){
? ? ? ? ? ? ? ? ? ? min = mid + 1;
? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ?else if(key < arr[mid]){
? ? ? ? ? ? ? ? ? ? ? ? ?max = mid -1;
? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ?if(mix>max)
? ? ? ? ? ? ? ? ? ?return -1;?
? ? ? ? ? ? ?mid = (max+min)/2;
? ? ? ? ? ? }
return mid;
}
折半查找的第二種方式:
public ?static int ?halfsearch(int arr[ ] ,int key){
? ? ? ? ? int min = 0 , max = arr.length-1, mid;
? ? ? ? ?while(min < =max){
? ? ? ? ? ? ? ? ?mid = (max + min)>>1;
? ? ? ? ? ? ? ? if(key>arr[mid])
? ? ? ? ? ? ? ? ? ? ? ?min = mid +1;l
? ? ? ? ? ? ? ? else if(key<arr[mid]){
? ? ? ? ? ? ? ? ? ? ? ? max = mid -1 ;
? ? ? ? ? ? ? else?
? ? ? ? ? ? ? ? ? ? ? ? return ?mid;
? ? ? ? ? ? ? }
? ? ? ?}
}
十進(jìn)制轉(zhuǎn)為二進(jìn)制:
public static void toBin(int num){
? ? ?while(num>0){
? ? ? ? ? ? System.out.println(num%2);
? ? ? ? ? ? ? num = num /2;
? ? ? ? }
}
十進(jìn)制轉(zhuǎn)為十六進(jìn)制:
public static void toHex(int num){
? ? ? ? ? ? ?StringBuffer sb = new StringBuffer();
? ? ? ? ? ? ?for( int ?x= 0; x < 8; x++){
int temp = num &15;
? ? ? ? ? ? ? ? ? ?if(temp>9){
? ? ? ? ? ? ? ? ? ? ? ?sb.append((char)(temp -10+'A'));
? ? ? ? ? ? ? ? ?else
? ? ? ? ? ? ? ? ? ? ? sb.append(temp);
? ? ? ? ? ? ? ? num = num >>>4;
? ? ? ? ? }
? ? ? System.out.println(sb.reverse());
? ? ? ?}
}
S2SH在一些實(shí)體類的例子里,有的沒有寫構(gòu)造方法,有的有寫構(gòu)造方法,有參數(shù)和無參數(shù)都有,是因?yàn)椋海?)創(chuàng)建java時(shí)會(huì)提供一個(gè)默認(rèn)的無參構(gòu)造方法,但是不會(huì)顯示出來;(2)根據(jù)業(yè)務(wù)的需求用戶可以自己定義帶參數(shù)的構(gòu)造方法;(3)至于參數(shù)幾個(gè),可以根據(jù)對(duì)應(yīng)的業(yè)務(wù)需求,制定加上相應(yīng)的參數(shù)。
構(gòu)造函數(shù)是一種特殊的函數(shù),主要功能是用來創(chuàng)建對(duì)象時(shí)初始化帝鄉(xiāng),即為對(duì)象成員變量賦初始值,總與bew運(yùn)算符一起使用在創(chuàng)建對(duì)象的語句中,構(gòu)造函數(shù)與類名相同,可重載多個(gè)不同的構(gòu)造函數(shù)。
Integer.parseInt(String)就是將String字符類型數(shù)據(jù)轉(zhuǎn)換為Integer整型數(shù)據(jù)。
Integer.parseInt(String)遇到一些不能被轉(zhuǎn)換為整型的字符時(shí),會(huì)拋出異常。
一個(gè)例子
str=bf.readLine() ;//bf是一個(gè)Buffer流,str是一個(gè)字符串
num=Integer.parseInt(str) ;//此處將str字符串轉(zhuǎn)換為整型并存儲(chǔ)到int類型的num中
其作用在于,若讀取的str不為整型,則會(huì)報(bào)錯(cuò),可以拋出異常解決此問題
try{
str=brd.readLine() ;
num=Integer.parseInt(str) ;
}
catch(Exception e)
{
System.out.println("對(duì)不起,只能輸入整數(shù),請(qǐng)重新輸入。") ;
}
如此,再次輸入h,a等非整型字符時(shí),則會(huì)提示你輸入整數(shù)
查表法:將所有的元素臨時(shí)存儲(chǔ)起來,建立對(duì)應(yīng)關(guān)系。每一次&15后的值作為索引去查建立好的表,都可以找對(duì)應(yīng)的元素
類和對(duì)象的關(guān)系:
類:對(duì)現(xiàn)實(shí)生活中事物的描述;對(duì)象:就是這類事物,實(shí)實(shí)在在存在的個(gè)體
屬性對(duì)應(yīng)類中變量,行為對(duì)應(yīng)類中的函數(shù)(方法)
其實(shí)定義類就是在描述事物,就是在定義屬性和行為。屬性和行為共同成為類中的成員(成員變量和方法)
堆內(nèi)存中的變量默認(rèn)初始化值----null
成員變量和局部變量:成員變量作用于整個(gè)類中,局部變量作用于函數(shù)中,或者語句中;在內(nèi)存中的位置,成員變量在堆內(nèi)存中,因?yàn)閷?duì)象的存在才在內(nèi)存總存在,而局部變量存在于棧內(nèi)存中
匿名對(duì)象使用方式一:當(dāng)對(duì)象的方法只調(diào)用一次時(shí)可以用匿名對(duì)象來完成,這樣寫比較簡化;如果對(duì)一個(gè)對(duì)象進(jìn)行多個(gè)成員調(diào)用,必須給這個(gè)對(duì)象起個(gè)名字
匿名對(duì)象的使用方式二:可以將匿名對(duì)象作為實(shí)際參數(shù)進(jìn)行傳遞
封裝:指隱藏對(duì)象的屬性和實(shí)現(xiàn)細(xì)節(jié),僅對(duì)外提供公共訪問方式;好處:將變化隔離、便于使用、提高重用性、提高安全性;封裝原則:將不需要對(duì)外提供的內(nèi)容都隱藏起來;把屬性都隱藏,提供公共方法對(duì)其訪問
private:私有,權(quán)限修飾符;用于修飾類中的成員(成員變量,成員函數(shù)),私有只在本類中有效,類以外即使建立了對(duì)象也不能直接訪問
私有僅僅是封裝的一種表現(xiàn)形式;之所以對(duì)外提供訪問方式,就因?yàn)榭梢栽谠L問方式中加入邏輯判斷等語句,對(duì)方問的數(shù)據(jù)進(jìn)行操作,提高代碼的健壯性
構(gòu)造函數(shù):
特點(diǎn):函數(shù)名與類名相同;不同定義返回值類型;不可以寫return語句;
作用:給對(duì)象進(jìn)行初始化;
注意:默認(rèn)構(gòu)造函數(shù)的特點(diǎn);多個(gè)構(gòu)造函數(shù)是以重載的形式存在的;當(dāng)一個(gè)類中沒有定義構(gòu)造函數(shù)時(shí),系統(tǒng)會(huì)默認(rèn)給該類加入一個(gè)空參數(shù)的構(gòu)造函數(shù);當(dāng)在類中自定義了構(gòu)造函數(shù)后,默認(rèn)的構(gòu)造函數(shù)就沒有了
重載:函數(shù)名相同,但是參數(shù)列表不同
構(gòu)造函數(shù)和一般函數(shù)在寫法上有不同,在運(yùn)行上也有不同;構(gòu)造函數(shù)是在對(duì)象一建立就運(yùn)行,給對(duì)象初始化,一般方法是對(duì)象調(diào)用才執(zhí)行,是給對(duì)象添加對(duì)象具備的功能;一個(gè)對(duì)象建立,構(gòu)造函數(shù)只運(yùn)行一次;而一般方法可以被該對(duì)象調(diào)用多次
構(gòu)造代碼塊
作用:給對(duì)象進(jìn)行初始化;對(duì)象一建立就運(yùn)行,而且優(yōu)先于構(gòu)造函數(shù)執(zhí)行;
與構(gòu)造函數(shù)的區(qū)別:構(gòu)造代碼塊是給所有對(duì)象進(jìn)行統(tǒng)一初始化;而構(gòu)造函數(shù)是給對(duì)應(yīng)的對(duì)象進(jìn)行初始化
構(gòu)造代碼塊中定義的是不同對(duì)象的共性的初始化內(nèi)容
this:用于區(qū)分局部變量和成員變量同名的情況;
特點(diǎn):代表本類的對(duì)象;代表它所在函數(shù)所屬對(duì)象的引用;簡單說,哪個(gè)對(duì)象在調(diào)用this所在的函數(shù),this就代表哪個(gè)對(duì)象
this的應(yīng)用:當(dāng)定義類中功能時(shí),給函數(shù)內(nèi)部要用到調(diào)用該函數(shù)的額對(duì)象時(shí),這時(shí)用this來表示這個(gè)對(duì)象。但凡本類功能內(nèi)部使用了本類對(duì)象,都用this表示
this語句:用于構(gòu)造函數(shù)之間進(jìn)行互相調(diào)用;只能定義在構(gòu)造函數(shù)的第一行(第一個(gè)語句),因?yàn)槌跏蓟瘎?dòng)作要先執(zhí)行。
static(靜態(tài))關(guān)鍵字:用于修飾成員(成員變量和成員函數(shù));被修飾后的成員具備以下特點(diǎn):隨著類的加載而加載;優(yōu)先于對(duì)象存在;可以直接被類名所調(diào)用;被所有對(duì)象共享;當(dāng)成員被靜態(tài)修飾后,就多了一個(gè)調(diào)用方式,除了可以被對(duì)象調(diào)用外,還可以直接被類名調(diào)用:類名.靜態(tài)成員
實(shí)例變量和類變量的區(qū)別:
1.存放位置:類變量隨著類的加載而存在于方法區(qū)中;實(shí)例變量隨著對(duì)象的建立而存在于堆內(nèi)存中
2.生命周期:類變量生命周期最長,隨著類的消失而消失;實(shí)例變量生命周期隨著對(duì)象的消失而消失
靜態(tài)的使用注意事項(xiàng):1.靜態(tài)方法只能訪問靜態(tài)成員;非靜態(tài)方法既可以訪問靜態(tài)也可以訪問非靜態(tài);2.靜態(tài)方法中不可以定義this.super關(guān)鍵字,因?yàn)殪o態(tài)優(yōu)先于對(duì)象存在,所以靜態(tài)方法總不可以出現(xiàn)this;3.主函數(shù)是靜態(tài)的
靜態(tài)的利與弊:
利:對(duì)對(duì)象的共享數(shù)據(jù)進(jìn)行單獨(dú)空間的存儲(chǔ),節(jié)省空間,沒有必要每一個(gè)對(duì)象總都存儲(chǔ)一份,可以直接被類名調(diào)用
弊:生命周期過長,訪問出現(xiàn)局限性(靜態(tài)雖好,只能訪問靜態(tài))
主函數(shù)是一個(gè)特殊的函數(shù),可以被jvm調(diào)用,作為程序的入口;
主函數(shù):
public:代表著該函數(shù)的訪問權(quán)限是最大的
static:代表著主函數(shù)隨著類的加載就已經(jīng)存在了
void:主函數(shù)沒有具體的返回值
main:不是關(guān)鍵字,但是是一個(gè)特殊的單詞,可以被jvm識(shí)別
函數(shù)的參數(shù):(String[]args):函數(shù)的參數(shù),參數(shù)的類型是一個(gè)數(shù)組,該數(shù)組中的元素是字符串。字符串類型的數(shù)組
主函數(shù)是固定格式的:jvm識(shí)別
jvm在調(diào)用主函數(shù)時(shí),傳入的是new String[0];
因?yàn)殪o態(tài)修飾的內(nèi)容有成員變量和函數(shù)。
當(dāng)對(duì)象中出現(xiàn)共享數(shù)據(jù)時(shí),該數(shù)據(jù)被靜態(tài)所修飾。
對(duì)象中的特有數(shù)據(jù)要定義成非靜態(tài)存在于堆內(nèi)存中
當(dāng)功能內(nèi)部沒有訪問到非靜態(tài)數(shù)據(jù)(對(duì)象的特有數(shù)據(jù))該功能可以定義成靜態(tài)的
靜態(tài)的應(yīng)用:
每一個(gè)應(yīng)用程序中都有共性的功能,可以將這些功能進(jìn)行抽取,獨(dú)立封裝,以便復(fù)用
雖然可以通過建立ArrayTool的對(duì)象使用這些工具方法,對(duì)數(shù)組進(jìn)行操作,但是發(fā)現(xiàn)了下面這些問題:
1.對(duì)象是用于封裝數(shù)據(jù)的,可是ArrayTool對(duì)象并未封裝特有數(shù)據(jù)
2.操作數(shù)組的每一個(gè)方法都沒有用到ArrayTool對(duì)象中的特有數(shù)據(jù)
所以這是不需要對(duì)象的,因此可以將ArrayTool中的方法都定義成static,直接通過類名調(diào)用即可
將方法都靜態(tài)后,可以方便于使用,但是該類還是可以被其他程序建立對(duì)象的,為了更為嚴(yán)謹(jǐn),強(qiáng)制讓該類不能建立對(duì)象,可以通過將構(gòu)造函數(shù)私有化完成
class ArrayTool{
? ? ? ? private? ArrayTool(){}
? ? ? ? ? ?...........(方法集合)
}
默認(rèn)打的構(gòu)造函數(shù)的權(quán)限是隨著類的變化而變化
靜態(tài)代碼塊:
特點(diǎn):隨著類的加載而執(zhí)行,只執(zhí)行一次,用于給類進(jìn)行初始化
格式:
static
{
? ?靜態(tài)代碼塊中的執(zhí)行語句
}
省略前面一些代碼
Person p = new Person("zhangsan",20);
該句話執(zhí)行的內(nèi)容:
1.因?yàn)閚ew用到了Person.calss,所以會(huì)先找到Person.class文件并加載到內(nèi)存中;
2.執(zhí)行該類中的static代碼塊,如果有的話,給Person.class類進(jìn)行初始化
3.在堆內(nèi)存中開辟空間,分配內(nèi)存地址
4.在堆內(nèi)存中建立對(duì)象的特有屬性,并進(jìn)行默認(rèn)初始化
5.對(duì)屬性進(jìn)行顯示初始化
6.對(duì)對(duì)象進(jìn)行構(gòu)造代碼塊初始化
7.對(duì)對(duì)象進(jìn)行對(duì)應(yīng)的構(gòu)造函數(shù)初始化
8.將內(nèi)存地址賦給內(nèi)存中的p變量
設(shè)計(jì)模式:
解決某一類問題最行之有效的方法;
單例設(shè)計(jì)模式:解決一個(gè)類在內(nèi)存中只存在一個(gè)對(duì)象;想要保證對(duì)象唯一,1.為了避免其他程序過多建立該對(duì)象,先控制禁止其他程序建立該對(duì)象;2.為了讓其他程序可以訪問到該對(duì)象,只好在本類中自定義一個(gè)對(duì)象;3。為了方便其他程序?qū)ψ远x對(duì)象的訪問,可以對(duì)外提供一些訪問方式,實(shí)現(xiàn)方式:
1.將構(gòu)造函數(shù)私有化
2.在類中創(chuàng)建一個(gè)本類對(duì)象
3.提供一個(gè)方法可以獲取到該對(duì)象
餓漢模式:single類一進(jìn)內(nèi)存,就已經(jīng)創(chuàng)建好了對(duì)象
class Single{
? ? ? ? ?private ?Single(){?}
? ? ? ? ?private? static? Single? s = new Single();?
? ? ? ? ? public ?static ? Single getInstance()
? ? ? ? ? {
? ? ? ? ? ? ? ? ? ?return ?s;
? ? ? ? ? ?}
}
class SingleDemo{
public static void main(String[]args){
? ? ? ? ?Single ss = Single.getInstance();
? ? ? ? ? }
}
對(duì)于事物該怎么描述還是怎么描述,當(dāng)需要將該事物的對(duì)象保證在內(nèi)存中唯一時(shí),就將以上的三步加上即可
下面這個(gè)為
懶漢模式:對(duì)象是方法被調(diào)用時(shí),才初始化,也叫做對(duì)象的延時(shí)加載;single類進(jìn)內(nèi)存,對(duì)象還沒有存在,只有調(diào)用了getInstance方法,才建立對(duì)象
class Single{
private ?Single(){?}
private? static? Single? s = null;
public ?static ? Single getInstance()
{
? ? if(s==null){
? ? ? ? synchronized(Single.class)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? if(s==null)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?s=new Single();
? ? ? ? ? ? ? ? }
}
? ? ? ? ? ? return s;
? ? ? ? ? }
}
原則:定義單例時(shí),使用餓漢式
繼承:
1.提高代碼的復(fù)用性
2.繼承讓類與類之間產(chǎn)生了關(guān)系,有了這個(gè)關(guān)系,才有了多態(tài)的特性剪壞
注意:千萬不要為了獲取其他類的功能,簡化代碼而繼承。必須是類與類之間有所屬關(guān)系才可以繼承。所屬關(guān)系 ?is ?a.
java只支持單繼承,不支持多繼承,因?yàn)槎嗬^承容易帶來安全隱患,當(dāng)多個(gè)父類中定義了相同功能,但是功能內(nèi)容不同時(shí),不確定運(yùn)行哪一個(gè),但是java保留了這種機(jī)制,并用另一種體現(xiàn)形式來完成表示,多實(shí)現(xiàn)
java支持多層繼承,也就是一個(gè)繼承體系,想要使用體系,先查閱體系中父類的描述,因?yàn)楦割愔卸x的是該體系中共性功能。通過了解共性功能,就可以知道該體系的基本功能,那么這個(gè)體系已經(jīng)可以基本使用了。 在具體調(diào)用時(shí),要?jiǎng)?chuàng)建最子類的對(duì)象,因?yàn)椋?)有可能父類不能創(chuàng)建對(duì)象,(2)創(chuàng)建子類對(duì)象可以使用更多的功能,包括基本的,也包括特有的
查閱父類功能,創(chuàng)建子類對(duì)象使用功能
聚集:has a
聚合,組合:
當(dāng)子類繼承父類,沿襲了父類的功能,到子類中,但是子類雖然有這個(gè)功能,但是功能的內(nèi)容卻和父類不一致,這時(shí),沒有必要定義新功能,而是使用覆蓋保護(hù),保留父類的功能定義,并重寫功能內(nèi)容
覆蓋:
子類覆蓋父類,必須保證子類權(quán)限大于等于父類權(quán)限,才可以覆蓋,否則編譯失敗
靜態(tài)只能覆蓋靜態(tài)
記?。褐剌d只看同名函數(shù)的參數(shù)列表,重寫看字符類方法樣一模一樣,返回值類型也要一樣
final可以修飾類,方法,變量
final修飾的類不可以被繼承
final修飾的方法不可以覆蓋
final修飾的變量是一個(gè)常量,只能被賦值一次
內(nèi)部類只能訪問被final修飾的局部變量
抽象的特點(diǎn):
1.抽象方法一定在抽象類中
2.抽象方法和抽象類都必須被abstract關(guān)鍵字修飾
3.抽象類中不可以用new創(chuàng)建對(duì)象,因?yàn)檎{(diào)用抽象方法沒意義
4.抽象類中的方法要被使用,必須由子類復(fù)寫其所有的抽象方法后,建立子類對(duì)象調(diào)用。如果子類只覆蓋了部分抽象方法,那么該子類還是一個(gè)抽象類
抽象類和一般類沒有太大的不同,該如何描述失誤,就如何描述事物,只不過,該事物出現(xiàn)了一些看不懂的東西,這些不確定的部分也是該事物的功能,需要明確出來,無法定義主體,通過抽象方法來表示
抽象類比一般類多了抽象函數(shù);抽象類不可以實(shí)例化,就是在類中可以定義抽象方法
抽象類中可以不定義抽象方法,這樣做僅僅是不讓該類建立對(duì)象
接口中的成員修飾符是固定的:
成員常量:public static final
成員函數(shù):public abstract
接口的出現(xiàn),將“多繼承”通過另一種形式體現(xiàn)出來,即“多實(shí)現(xiàn)”
接口(interface):初期理解,可以認(rèn)為是一個(gè)特殊的抽象類;當(dāng)抽象 類中的方法都是抽象的,那么該類可以通過接口的形式來表示
class用于定義類;interface用于定義接口;接口中的成員都是public的
接口是不可以創(chuàng)建對(duì)象的,因?yàn)橛谐橄蠓椒?,需要被子類?shí)現(xiàn),子類對(duì)接口中的抽象方法全都覆蓋后,子類才可以實(shí)例化,否則子類是一個(gè)抽象類
接口是對(duì)外暴漏的規(guī)則;是程序的功能擴(kuò)展;可以用來多實(shí)現(xiàn);類與接口之間是實(shí)現(xiàn)關(guān)系,而且類可以繼承一個(gè)類的同時(shí)實(shí)現(xiàn)多個(gè)接口;接口與接口之間可以有繼承關(guān)系
多態(tài):可以理解為事物存在的多種體現(xiàn)形態(tài)
1.多態(tài)的體現(xiàn):父類的引用指向了自己的子類對(duì)象;父類的引用也可以接收自己的子類對(duì)象。
2.多態(tài)的前提
必須是類與類之間有關(guān)系,要么繼承,要么實(shí)現(xiàn);通常還有一個(gè)前提,就是覆蓋
3.多態(tài)的好處
多態(tài)的出現(xiàn)大大的提高了程序的擴(kuò)展性
弊端:只能使用父類的引用訪問父類的成員
4.多態(tài)的應(yīng)用
5.多態(tài)使用的注意事項(xiàng)
我們能轉(zhuǎn)換的是父類引用指向了自己的子類對(duì)象,該應(yīng)用可以被提升,也可以被強(qiáng)制轉(zhuǎn)換
在多態(tài)中成員函數(shù)的特點(diǎn):
在編譯時(shí)期:參閱引用型變量所屬的類中是否有調(diào)用的方法。如果有,編譯通過,如果沒有編譯失敗
在運(yùn)行時(shí)期:參閱對(duì)象所屬的類中是否有調(diào)用的方法。
簡單總結(jié):成員函數(shù)在多態(tài)調(diào)用時(shí),編譯看左邊,運(yùn)行看右邊
在多態(tài)中,成員變量的特點(diǎn),無論編譯和運(yùn)行,都參考左邊(引用型變量所屬的類型)
在多態(tài)中,靜態(tài)成員函數(shù)的特點(diǎn):無論編譯和運(yùn)行,都參考左邊
主板案例:
Interface PCI
{
? ? ? ? ?public void open();
? ? ? ? ?public void close();
}
class MainBoard
{
? ? ? ? ? ? public void run()
? ? ? ? ? ? ?{
? ? ? ? ? ? ? ? ? ? ? ? ?System.out.println("MainBoard ? run");?
? ? ? ? ? ? ?} ?
? ? ? ? ? ? public void usePCI(PCI p)
? ? ? ? ? ?{
? ? ? ? ? ? ? ? ? ? ? ? p.open();
? ? ? ? ? ? ? ? ? ? ? ? p.close();
? ? ? ? ? }
}
class NetCard implements PCI
? ?{
? ? ? ? ? ? ?public void open()
? ? ? ? ? ? ?{
? ? ? ? ? ? ? ? ? ? System.out.println("run");
? ? ? ? ? ? }
? ? ? ? ? ? ? public void close()
? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? System.out.println("close");
? ? ? ? ? ? ? ?}
?}
?class ZhuBan
? ?{
? ? ? ? ? ?public static void ?main(String[] args)
? ? ? ? ?{
? ? ? ? ? ? ? ? ? MainBoard mb = new MainBoard();
? ? ? ? ? ? ? ? ?mb.run();
? ? ? ? ? ? ? ? ?mb.usePCI(NetCard);
? ? ? ? ?}
}
Object是所有對(duì)象的直接或者間接父類,傳說中的上帝;該類中定義的是所有對(duì)象都具備的功能。
Object類中已經(jīng)提供了對(duì)對(duì)象是否相同的比較方法,如果自定義類中也有比較相同的功能,沒有必要重新定義,紫瑤演戲父類中的功能,建立自己特有的內(nèi)容即可,這就是覆蓋
內(nèi)部類可以直接訪問外部類中的成員,包括私有成員(之所以可以直接訪問外部類中的成員,是因?yàn)閮?nèi)部類中持有了一個(gè)外部類的引用,格式:外部類名.this);而外部類要訪問內(nèi)部類中的成員必須要建立內(nèi)部類的對(duì)象
訪問格式:
1.當(dāng)內(nèi)部類定義在外部類的成員位置上,而且非私有,可以在外部其他類中,直接建立內(nèi)部類對(duì)象:
格式:
? ? ?外部類名.內(nèi)部類名 ?變量名 = 外部類對(duì)象.內(nèi)部類對(duì)象;
2.當(dāng)內(nèi)部類在成員位置上,就可以被成員修飾符所修飾
? ?比如:private:將內(nèi)部類在外部類中進(jìn)行封裝;static:內(nèi)部類就具備static的特性
? ?當(dāng)內(nèi)部類被static修飾后,只能訪問外部類中的static成員,出現(xiàn)了訪問局限
? 在外部其他類中,直接訪問static內(nèi)部類的非靜態(tài)成員:
? ?new ? Outer.Inner().function();
在外部其他類中,直接訪問static內(nèi)部類的靜態(tài)成員:
? Outer.Inner.function();
注意:當(dāng)內(nèi)部類中定義了靜態(tài)成員,該內(nèi)部類必須是靜態(tài)的;當(dāng)外部類中的靜態(tài)方法訪問內(nèi)部類時(shí),內(nèi)部類也必須是static的
當(dāng)描述事物時(shí),事物的內(nèi)部還有事物,該事物用內(nèi)部類來描述。
因?yàn)閮?nèi)部事務(wù)在使用外部事物的內(nèi)容
內(nèi)部類定義在局部時(shí):1.不可以被成員修飾符修飾;2.可以直接訪問外部類中的成員,因?yàn)檫€持有外部類中的引用。但是不可以訪問它所在的局部中的變量。只能訪問被final修飾的局部變量
匿名內(nèi)部類:
1.匿名內(nèi)部類就是內(nèi)部類的簡寫格式
2.定義匿名內(nèi)部類的前提:內(nèi)部類必須繼承一個(gè)類或者實(shí)現(xiàn)接口
3.匿名內(nèi)部類的格式:new ?父類或者接口(){定義子類的內(nèi)容}
4.其實(shí)匿名內(nèi)部類就是一個(gè)匿名子類對(duì)象。而且這個(gè)對(duì)象有點(diǎn)胖,可以理解為帶內(nèi)容的對(duì)象
5.匿名內(nèi)部類中定義的方法最好不要超過3個(gè)
異常
異常的體系:
Throwable
Error :通常出現(xiàn)重大問題如:運(yùn)行的類不存在或者內(nèi)存溢出等;不編寫針對(duì)代碼對(duì)其處理
Exception:在運(yùn)行時(shí)運(yùn)行出現(xiàn)的一些情況,可以通過try catch finally
Exception和Error的子類名都是以父類名作為后綴
異常就是程序在運(yùn)行時(shí)出現(xiàn)的不正常情況
異常的由來:問題也是現(xiàn)實(shí)生活中一個(gè)具體的事物,也可以通過java的類的形式進(jìn)行描述,并封裝成對(duì)象,其實(shí)就是java對(duì)不正常情況進(jìn)行描述后的對(duì)象體現(xiàn)
對(duì)于問題的劃分,分為:一種是嚴(yán)重的問題,一種是非嚴(yán)重的問題
try
{ 需要被檢測的代碼}
catch(異常類 變量)
{處理異常的代碼;(處理方式)}
finally{一定會(huì)執(zhí)行的語句}
對(duì)捕獲到的異常對(duì)象進(jìn)行常見方法操作:
其實(shí)jvm默認(rèn)的異常處理機(jī)制,就是在調(diào)用printStackTrace方法,打印異常的堆棧的跟蹤信息。
在功能上通過throws的關(guān)鍵字聲明了該功能有可能出現(xiàn)的問題
對(duì)捕獲到的異常對(duì)象進(jìn)行常見方法操作; String getMessage():獲取異常信息
在函數(shù)上聲明異常:便于提高安全性,讓調(diào)用出進(jìn)行處理,不處理編譯失敗
對(duì)多異常的處理:
1.聲明異常時(shí),建議聲明更為具體的異常,這樣處理的可以更具體
2.對(duì)方聲明幾個(gè)異常,就對(duì)應(yīng)有幾個(gè)catch塊;如果多個(gè)catch中的異常出現(xiàn)繼承關(guān)系,父類異常catch塊 放在最下面,不要定義多余的catch塊
3.建議在進(jìn)行catch處理時(shí),catch中一定要定義具體處理方式,不要簡單定義一句e.printStackTrace(),也不要簡單的就書寫一條輸出語句
因?yàn)轫?xiàng)目中會(huì)出現(xiàn)特有 的問題,而這些問題并未被java鎖描述并封裝對(duì)象,所以對(duì)于這些特有的問題可以按照java對(duì)問題封裝的思想對(duì)特有的問題,進(jìn)行自定義的異常封裝
自定義異常:必須繼承Exception;繼承exception的原因,異常體系的特點(diǎn),因?yàn)楫惓?duì)象和異常類都會(huì)被拋出,因?yàn)樗麄兌季邆淇蓲佇?,這個(gè)可拋性是Throwable這個(gè)體系中的獨(dú)有特點(diǎn),只有這個(gè)體系中的類和對(duì)象才可以被throws和throw操作,
當(dāng)在函數(shù)內(nèi)部出現(xiàn)了throw拋出異常對(duì)象,那么就必須要給對(duì)應(yīng)的處理動(dòng)作:
1.要么在內(nèi)部try ncatch處理
2.要么在函數(shù)上聲明讓調(diào)用者處理
一般情況下,函數(shù)內(nèi)出現(xiàn)異常,函數(shù)上需要聲明
throw和throws的區(qū)別:throws使用在函數(shù)上,throw使用在函數(shù)內(nèi);throws后面跟的是函數(shù)類,可以跟多個(gè),用逗號(hào)隔開;throw后面跟的是函數(shù)對(duì)象
Exception中有一個(gè)特殊的子類異常RuntimeException運(yùn)行時(shí)異常;如果在函數(shù)內(nèi)拋出該異常,函數(shù)上可以不用聲明,編譯一樣通過,如果在函數(shù)上聲明了該異常,調(diào)用者可以不用進(jìn)行處理,編譯一樣通過
自定義異常時(shí),如果該異常的發(fā)生,無法再繼續(xù)進(jìn)行運(yùn)算,就讓自定義異常繼承RuntimeException
對(duì)于異常分為兩種:
1.編譯時(shí)被檢測的異常;
2.編譯時(shí)不被檢測的異常(運(yùn)行時(shí)異常,RuntimeException以及其子類)
finally代碼塊:一定執(zhí)行的代碼塊,通常用于關(guān)閉資源;finally只有一種情況不會(huì)執(zhí)行,當(dāng)執(zhí)行到System.exit(0);finally不會(huì)執(zhí)行
catch是用于處理異常,如果沒有catch就代表異常沒有被處理過,如果該異常是檢測時(shí)異常,那么必須聲明。
1.子類在覆蓋父類時(shí),如果父類的方法拋出異常,那么子類的覆蓋方法,只能拋出父類的異?;蛘咴摦惓5淖宇?/p>
2.如果父類方法拋出多個(gè)異常,那么子類在覆蓋該方法時(shí),只能拋出父類異常的子集
3.如果父類或者接口的方法中沒有異常拋出,那么子類在覆蓋方法時(shí)也不可以拋出異常,如果子類方法發(fā)生了異常就必須要進(jìn)行try處理,絕對(duì)不能拋
異常的好處:
1.將問題進(jìn)行封裝
2.將正常流程代碼和問題處理代碼相分離,方便于閱讀
異常的處理原則:
1.兩種:try或者拋
2.調(diào)用到配偶出異常的功能時(shí),拋出幾個(gè),就處理幾個(gè)
3.多個(gè)catch,父類的catch放到最下面
4.catch內(nèi)需要定義針對(duì)性的處理方式,不要簡單的定義printstacktrace,或者輸出語句,也不要不寫;當(dāng)捕獲到的異常,本功能處理不了的時(shí)候,可以繼續(xù)在catch中拋出;如果該異常處理不了,但并不屬于該功能出現(xiàn)的異常,可以將異常轉(zhuǎn)化后再拋出和該功能相關(guān)的異?;蛘弋惓?梢蕴幚淼枰獙惓.a(chǎn)生后和本功能相關(guān)的問題提供出去,讓調(diào)用者知道并進(jìn)行處理,也可以將捕獲異常處理后轉(zhuǎn)換新的異常