Java 基礎(chǔ)語法讓你弄懂類和對象
Java 基礎(chǔ)語法
其實在學習 C 語言時就一直聽到 C 語言是面向過程的,而 Java 是面向?qū)ο蟮倪@句話。并且我們之前的學習中也遇到了類,但是對它好像沒有其他的認知。
那么面向過程與面向?qū)ο蟮降资鞘裁茨??它們有哪些不同的意義呢?
類與對象到底是什么呢?這章就來帶你揭曉!
一、類與對象的初步認知
我們可以舉一個洗衣服的例子來認識面向?qū)ο蠛兔嫦蜻^程
對于面向過程: 我們可以看成是手洗衣服的過程
對于面向?qū)ο螅?我們可以看作直接用洗衣機去洗
其中總共有四個對象:人、衣服、洗衣粉、洗衣機
而整個洗衣服的過程就是:人將衣服放進洗衣機、人倒入洗衣粉、人啟動洗衣
因此整個過程主要就是上述四個對象之間交互完成的,人不需要關(guān)心洗衣機具體是如何洗衣服并且甩干的
因此對于面向?qū)ο?,重點就是
找對象
創(chuàng)建對象
使用對象
那么對象從何而來呢?它其實是由類的實例化產(chǎn)生的
下面讓我們來了解類以及類的實例化吧!
二、類和類的實例化
類
就是一類對象的統(tǒng)稱
對象
就是這一類具體化的一個實例
舉個栗子講講
比如我們做月餅的模子就是一個類,而通過這個模子可以做出月餅。那么在這個例子中,做月餅的模子就是類,而那個月餅就是對象。并且一個月餅就是一個實體,而一個模子可以實例化無數(shù)個對象,也就是說一
個類可以產(chǎn)生無數(shù)的對象
那怎么聲明一個類呢?首先我們要知道
聲明一個類就是創(chuàng)建一個新的數(shù)據(jù)類型(感覺類似于 C 語言中的 struct)
類在 Java 中屬于引用類型
Java 使用關(guān)鍵字 class 來聲明類,并且類中可以定義一些屬性和行為
上個代碼看看
// 定義一個類 class Person{ // 屬性(成員變量) public int age; public String name; // 行為(成員方法) public void eat(){ System.out.println("吃飯"); int a = 10; // 局部變量 } }
其中 Person 就是類名,{} 中的就是類的主體
。類里面可以創(chuàng)建屬性和行為
注意:
此處寫的方法不帶關(guān)鍵字 static
類的實例化
用類類型創(chuàng)建對象的過程,稱為類的實例化
我們要理解
- 類只是一個模型一樣的東西,限定了類有哪些成員變量
- 一個類可以實例化出多個對象,實例化出的對象會占用實際的物理空間,存儲類成員變量
- 就如上述的月餅的例子,類就如一個模子,并沒有實際的存在,實例化出的對象才能實際存儲數(shù)據(jù),占用物理空間
// 定義一個類 class Person{ // 屬性(成員變量) public int age; public String name; // 行為(成員方法) public void eat(){ System.out.println("吃飯"); int a = 10; // 局部變量 } } public class Main{ public static void main(String[] args){ // 通過 new 實例化一個對象 Person person = new Person(); // 成員方法調(diào)用需要使用對象的引用調(diào)用 person.eat(); } } // 結(jié)果為:吃飯
其中 Person 為我們創(chuàng)建的類,person 為我們使用 Person 類創(chuàng)建的引用類型。關(guān)鍵字 new 用于創(chuàng)建一個對象的實例。使用 .
符號來訪問對象中的屬性和方法(既包含讀,也包含寫)
我們可以看一下在內(nèi)存中上述代碼是怎么存儲的
注意 Person 類中定義的 a 是一個局部變量,因為它在方法里面。而局部變量保存在棧中,而實例化的對象以及該類中的類成員變量,保存在堆中
三、類的成員
類的成員可以包含:字段、方法、代碼塊、內(nèi)部類和接口等
1. 字段/屬性/成員變量
在類中但是在方法外部定義的變量,我們稱為:“字段”或“屬性”或“成員變量”(一般不嚴格區(qū)分)
我們可以對上述創(chuàng)建的對象進行調(diào)用
class Person{ public int age; public String name; } public class Main{ public static void main(String[] args){ Person person = new Person(); System.out.println("age = " + person.age); System.out.println("name = " + person.name); } } // 結(jié)果為: // age = 0 // name = null
結(jié)果居然為 0 和 null,這是因為在 Java 中有一個默值認規(guī)則。
如果一個對象的字段沒有設(shè)置初始值,那么就會被設(shè)置為一個默認的值
- 對于各類數(shù)字類型,默認值為0 或者 0.0
- 對于 boolean 類型,默認值為 false
- 對于引用類型(String、Array、以及自定制類),默認值為 null
- 對于 char 類型,默認值為 ‘\u0000'
因此我們要注意,如果字段本身沒有初始值,且使用前沒有初始化,可能調(diào)用時會出現(xiàn)異常(使用引用類型時),如
class Person{ public int age; public String name; } public class Main{ public static void main(String[] args){ Person person = new Person(); System.out.println(person.name.length); } } // 會出現(xiàn) NullPointerException 異常
2. 方法
方法其實之前就專門講過了,這里就特意講兩點
- 如果我們要想知道我們的對象里面有什么變量、值為多少,就類似于要做一個 show 方法去展示。但是如果想看的類很多,就很麻煩,這是我們可以使用一下步驟(編譯器:IDEA)
在該類的空白處,點擊右鍵就可以看到 Generate
- 再點擊它,再找到 toString() 再點擊就會出現(xiàn)以下代碼(以上步驟可以使用快捷鍵:Alt + Insert 實現(xiàn))
@Override public String toString() { return "Person{" + "age=" + age + ", name='" + name + '\'' + '}';其中 @Override 叫做重寫的注解,就解釋了這段代碼是重寫的,又 toString 屬于 objet 的方法,所以就是重寫了 object 方法
為什么要這么做呢?如果我們直接通過
System.out.println(person); // 結(jié)果為:Person@1b6d3586
但是如果我們講上述步驟完成后結(jié)果就變成了
// 結(jié)果為:Person{age=0.0, name='null'}
這是因為上述步驟修改了 object 類中的 toString 方法
這里我們與不重寫前的結(jié)果比較可以知道 toString 方法 @ 后一段的內(nèi)容應該就是表示地址
因此我們通過上面步驟對 toString 進行重寫,就可以直接通過打印對象來得到該對象中的參數(shù)。并且我們將重寫內(nèi)的值改變,打印結(jié)果也會改變,如
@Override public String toString() { return "Person{" + "年齡=" + age + ", 名字='" + name + '\'' + '}';
打印結(jié)果就會改變?yōu)?/p>
// 結(jié)果為:Person{年齡=0.0, 名字='null'}
- 還有一點是關(guān)于構(gòu)造方法的,下面會講到!
3. static 關(guān)鍵字
上述的成員變量以及方法其實都是普通的成員變量以及方法,在 Java 中還有一種靜態(tài)成員變量(也叫類變量)和靜態(tài)成員方法。它們是由 static 修飾的
那么 static 有什么作用呢?
- 修飾屬性
- 修飾方法
- 代碼塊
- 修飾類
修飾屬性:
如果在成員變量前加上 static,此變量就叫做靜態(tài)變量
- 靜態(tài)變量屬于類,和具體的實例無關(guān)。也就是同一個類的不同實例公用一個靜態(tài)屬性
- 可以直接調(diào)用靜態(tài)變量,而無需創(chuàng)建類的實例
- 靜態(tài)變量存儲在方法區(qū)
我們來看一個代碼
class Person{ public static int cnt; public static void speak(){ System.out.println("我是靜態(tài)成員方法!"); } } public class Main{ public static void main(String[] args){ System.out.println("cnt = " + Person.cnt); Person.speak(); } } // 打印結(jié)果為: // cnt = 0 // 我是靜態(tài)成員方法!
大家注意沒,我調(diào)用時是直接使用的類名,而不是對象名。這就是靜態(tài)變量與普通成員變量的第一點不同,調(diào)用時直接使用類名。
既然和實例無關(guān)那會不會靜態(tài)變量的存儲也會不同,我們開看一個代碼
class Test{ public int a; public static int count; } public class Main{ public static void main(String[] args) { Test t1 = new Test(); t1.a++; Test.count++; System.out.println(t1.a); System.out.println(Test.count); System.out.println("============"); Test t2 = new Test(); t2.a++; Test.count++; System.out.println(t2.a); System.out.println(Test.count); } } // 結(jié)果為: /** 1 1 ============ 1 2*/
這是因為 count 被 static 修飾后,所有類共享,并且其存儲區(qū)域在方法區(qū)
修飾方法:
- 靜態(tài)方法屬于類,而不屬于類的對象
- 可以直接調(diào)用靜態(tài)方法,而無需創(chuàng)建類的實例
- 靜態(tài)方法只能訪問靜態(tài)數(shù)據(jù)成員,并且可以更改靜態(tài)數(shù)據(jù)成員的值
看一段代碼
class Person{ int a; public static int cnt; public static void speak(){ cnt = 10; //a = 100; 會報錯,因為訪問量非靜態(tài)數(shù)據(jù)成員 System.out.println("我是靜態(tài)成員方法!"); } }
注意:
this 和 super 兩個關(guān)鍵字不能在靜態(tài)上下文中使用(this 是當前實例的引用, super 是當前實例父類實例的引用,也是和當前實例相關(guān))【后面會介紹到!】
小結(jié):
就用一段代碼作為總小結(jié)吧
class Person{ public int age; // 實例變量(屬于對象) public static int count; // 靜態(tài)變量,編譯時已經(jīng)產(chǎn)生(屬于類本身),只有一份且存放在方區(qū) public final in SIZE = 10; // 被 final 修飾的叫常量,后續(xù)不可以更改(屬于對象) public static final in COUNT = 99; // 靜態(tài)的常量(屬于類本身) // 實例成員函數(shù) public void eat(){ int a = 10; //局部變量(存放在棧中) } // 靜態(tài)成員函數(shù) public static void staticTest(){ //不能訪問非靜態(tài)成員 // age = 10; 會報錯 System.out.println("StaticTest()"); } } public class Main{ public static void main(String[] args){ // 產(chǎn)生對象 實例化對象 Person person = new Person();// person 為對象的引用 System.out.println(person.age);// 默認值為0 //System.out.println(person.count);// 會有警告! // 正確訪問方式: System.out.println(Person.count); System.out.println(Person.COUNT); Person.staticTest(); // 總結(jié):所有被 stati c所修飾的方法或者屬性,全部不依賴于對象。 person.eat(); } }
為啥 main 函數(shù)是靜態(tài)的,如果是非靜態(tài)的可以啵,比如
class TestDemo{ public void main(String[] args){ TestDemo testDemo = new TestDemo(); testDemo.main(); } }
按照非普通成員方法的形式,如果 mian 函數(shù)要調(diào)就是上述代碼吧。但大家發(fā)現(xiàn)一個問題沒?
如果此時要使用 main 方法,就需要使用對象調(diào)用,那么好我們就在 main 方法里創(chuàng)建對象并且調(diào)用好了吧。誒?不對呀,要調(diào)用 main 方法就要使用對象?。浚??可我們創(chuàng)建的對象在 main 方法里面,怎么調(diào)用???
所以 main 方法要加上 static !
還有一點就是靜態(tài)方法里面可以調(diào)用普通方法嗎?no!
- 調(diào)用普通方法,就要用對象的引用
- 而靜態(tài)方法的使用是直接使用類,不需要創(chuàng)建對象
- 所以靜態(tài)方法里不能使用普通方法
四、封裝
其實上面關(guān)于類主要也就是講了類的實現(xiàn)和類的調(diào)用。如果我們以后使用了別人實現(xiàn)的類,結(jié)果后來別人修改了里面的某個變量名。人傻了?我們要一個一個修改原有的變量名嗎?
因此出現(xiàn)了一種方法叫做:封裝
封裝的本質(zhì)就是讓類的調(diào)用者不必太多了解類的實現(xiàn)者是如何實現(xiàn)類的,只要知道如何使用就行
1. private 實現(xiàn)封裝
private / public 這兩個關(guān)鍵字表示訪問權(quán)限控制
- 被 public 修飾的成員變量或者成員方法,可以直接被類的調(diào)用者使用
- 被 private 修飾的成員變量或者方法,不能直接被類的調(diào)用者使用
如果我們使用 public 修飾,那么類的實現(xiàn)的代碼被修改了,可能你創(chuàng)建的代碼就要花很多精力去維護。因此在實際中,我們一般用 private,至于 public 的使用要視情況而定,并且最好一個類只提供一個必要的 public 方法
讓我們看一個代碼更好的理解上述意思
class Person{ private int age = 13; private String name = "ZhangSan"; public void show(){ System.out.println("name = "+name + " age = "+age); } } } public class Main{ public static void main(String[] args){ Person person = new Person(); person.show(); } } // 結(jié)果為:name = ZhangSan age = 13
上述代碼就是使用了 private 修飾,所以主類里面不可以使用 age 和 name,而當我們要輸出它們時,就可以直接使用 show 方法,無論實現(xiàn) Person 類的函數(shù)中的 name 和 age 怎么改變,都可以正常打印。
如果你想獲取或者修改這個 private 屬性,那么就要用到接下來介紹的 getter / setter 方法
2. getter 和 setter 方法
使用這個方法可以在所創(chuàng)建的類中空白處右擊鼠標,選擇 Generate,就會出現(xiàn)
然后點擊就可以。Getter 是獲取這個屬性,Setter 是修改這個屬性,我們用上述代碼示范
class Person{ private double age; private String name; // 使用 setter 和 getter 方法 public double getAge() { return age; } public void setAge(double age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } } public class Main{ public static void main(String[] args){ Person person = new Person(); person.setAge(13); person.setName("張三"); double age = getAge(); String name = getName(); System.out.println("姓名:" + name + " 年齡:" + age); } } // 打印結(jié)果為:姓名:張三 年齡:13
注意
大家有注意沒,上述 setter 方法的代碼
public void setAge(double age) { this.age = age; }
其中 this 是啥,為啥要用它呢?首先其實這份代碼可以改成這樣public void setAge(double Myage) { age = Myage; }其中我將形參修改了,反正 Myage 就表示我要修改成的值,如果我不修改,直接這樣可以嗎
public void setAge(double age) { age = age; }應該不行對吧,因為此時的 age 就表示該方法里面的了,不能將對象的值進行修改。所以為我們此時引入 this
this 表示當前對象的引用
五、構(gòu)造方法
我們要知道,使用對象時,new 執(zhí)行了兩個過程
- 為對象分配內(nèi)存
- 調(diào)用對象的構(gòu)造方法
第二點的構(gòu)造方法是啥???其實我們上述代碼都都用到啦!
因為如果你自己沒有創(chuàng)建構(gòu)造方法的話,編譯器會默認提供一個不帶參數(shù)的構(gòu)造方法
那什么又是不帶參數(shù)的構(gòu)造方法呢?
1. 基本語法
首先我們要知道構(gòu)造方法的語法規(guī)則
- 方法名必須與類名相同
- 構(gòu)造方法沒有返回值
- 每一個類中至少定義一個構(gòu)造方法(沒有明確定義,系統(tǒng)會自動生成一個無參構(gòu)造,如果自己定義了,默認構(gòu)造將不再生成)
我們來看一個構(gòu)造無參的構(gòu)造方法吧!
class Person{ private double age; private String name; public Person(){ System.out.println("這是一個無參的構(gòu)造方法"); } } public class Main{ public static void main(String[] args){ Person person = new Person(); } } // 結(jié)果為:這是一個無參的構(gòu)造方法
既然有無參數(shù)的,那么也有有參數(shù)的
class Person{ private double age; private String name; public Person(){ System.out.println("這是一個無參的構(gòu)造方法"); } public Person(double age, String name){ this.age = age; this.name = name; System.out.println("這是一個有參的構(gòu)造方法"); } public void show(){ System.out.println("name: "+name+" age: "+age); } } public class Main{ public static void main(String[] args){ Person person1 = new Person(); Person person2 = new Person(13, "張三"); person2.show(); } } // 結(jié)果為: // 這是一個無參的構(gòu)造方法 // 這是一個有參的構(gòu)造方法 // name:張三 age:13
小結(jié)
構(gòu)造方法不僅僅可以構(gòu)造對象,同時也可以幫助我們進行成員變量的初始化
上述代碼里面的構(gòu)造方法其實構(gòu)成了重載(方法名相同、參數(shù)列表不同、返回值不做要求)
2. this 關(guān)鍵字
其實上面已經(jīng)講了 this,但是大家要格外注意,this 是表示當前對象的引用(注意不是當前對象)原因如下
對象的形成要經(jīng)過兩步:1. 為對象分配內(nèi)存 2. 調(diào)用合適的構(gòu)造方法
而我們使用 this 時,其實我們已經(jīng)完成了內(nèi)存的分配,但我們并沒有完成構(gòu)造方法的調(diào)用,所以此時還不能說創(chuàng)建了對象,只是將對象的地址得到了,也就是對象的引用
this 的用法
this.成員變量:調(diào)用成員變量
this.成員方法:調(diào)用成員方法
this() :調(diào)用其他的構(gòu)造方法
其中調(diào)用成員變量我們上面用了很多了,接下來我們先看下調(diào)用成員方法吧!
class Person{ private double age; private String name; public Person(double age, String name){ this.age = age; this.name = name; System.out.println("這是一個有參的構(gòu)造方法"); } public void show(){ System.out.println("name: "+name+" age: "+age); this.eat(); } public void eat(){ System.out.println("吃飯"); } } public class Main{ public static void main(String[] args){ Person person = new Person(13, "張三"); person.show(); } } // 結(jié)果為: // 這是一個有參的構(gòu)造方法 // name:張三 age:13 // 吃飯
上述代碼的 show 方法中就用到了 this 調(diào)用成員方法。接下來我們再看看怎么調(diào)用其他構(gòu)造的方法
class Person{ private double age; private String name; public Person(){ this(15, "李四"); System.out.println("這是一個無參的構(gòu)造方法"); } public Person(double age, String name){ this.age = age; this.name = name; System.out.println("這是一個有參的構(gòu)造方法"); } public void show(){ System.out.println("name: "+name+" age: "+age); } } public class Main{ public static void main(String[] args){ Person person = new Person(); person.show(); } } // 結(jié)果為: // 這是一個有參的構(gòu)造方法 // 這是一個無參的構(gòu)造方法 // name:李四 age:15
大家看結(jié)果,自己思考下執(zhí)行的順序
注意
使用 this() 調(diào)用構(gòu)造函數(shù),必須放在第一行
不能在靜態(tài)方法中使用
六、認識代碼塊
1. 什么是代碼塊
代碼塊就是
根據(jù)代碼塊定義的位置以及關(guān)鍵字,可以分為四種
本地代碼塊
實例代碼塊(也叫構(gòu)造代碼塊)
靜態(tài)代碼塊
同步代碼塊(這個先不講,俺也不會)
2. 本地代碼塊
本地代碼塊是定義在方法中,比如
public class Main{ public static void main(String[] args) { { int x = 10 ; System.out.println("x1 = " +x); } int x = 100 ; System.out.println("x2 = " +x); } }
這個在 C 語言里也見過,但幾乎沒用過
3. 實例代碼塊
構(gòu)造代碼塊是定義在類中(且不加修飾符)
一般用于初始化實例成員變量
class Person{ private double age; private String name; public Person(){ System.out.println("這是一個無參的構(gòu)造方法"); } // 實例代碼塊 { this.name = "Yb"; this.age = 15; System.out.println("實例代碼塊"); } } public class Main{ public static void main(String[] args){ Person person = new Person(); } }
4. 靜態(tài)代碼塊
靜態(tài)代碼塊是定義在類中(且加上 static 修飾)
一般用于初始化靜態(tài)成員屬性和需要提前準備的一些數(shù)據(jù)
class Person{ private double age; private String name; public Person(){ System.out.println("這是一個無參的構(gòu)造方法"); } // 實例代碼塊 {this.name = "Yb"; this.age = 15; System.out.println("實例代碼塊"); } // 靜態(tài)代碼塊 static{ // 不能用 this // this.age = 15; 會報錯 System.out.println("靜態(tài)代碼塊"); } } public class Main{ public static void main(String[] args){ Person person1 = new Person(); Person person2 = new Person(); } } // 結(jié)果為: /** 靜態(tài)代碼塊 實例代碼塊 這是一個無參的構(gòu)造函數(shù) 實例代碼塊 這是一個無參的構(gòu)造函數(shù) */使用 {} 定義的一段代碼
注意:上述代碼的打印結(jié)果,是先實行靜態(tài)代碼塊,再實行實例代碼塊,最后才執(zhí)行構(gòu)造函數(shù),并且在同一個類中,靜態(tài)代碼塊不管生成多少對象,只會執(zhí)行一次
七、補充說明
1. toString 方法
其實上面已經(jīng)講到了,重寫 object 的 toString 方法,將對象自動轉(zhuǎn)換成字符串,因此不需要使用 show 方法去查看對象的參數(shù)
因此這里就再重述一些知識點
- toString 方法會在使用 println 的時候被自動調(diào)用
- 將對象轉(zhuǎn)換成字符串這樣的操作叫做序列化
- toString 使 Object 提供的方法,我們自己創(chuàng)建的 Person 類默認繼承了 Object 類,可以重寫 toString 方法實現(xiàn)我們自己的版本
- @Override 在 Java 中稱為注釋,上述代碼中的 @Override 表示下面實現(xiàn)的 tostring 方法使重寫了父類的方法
2. 匿名對象
匿名對象顧名思義是表示沒有名字的對象,即沒有引用對象,可以看下面的代碼
// 不使用匿名對象 Person person = new Person(); person.eat(); // 使用匿名對象 new Person().eat();
并且如果一個對象只是用一次,后面不需要使用了,可以考慮使用匿名對象.。理由如下
// 不使用匿名對象 Person person = new Person(); person.eat(); person.show(); // 使用匿名對象 new Person().eat(); new Person().show();
其中我們注意到,不使用匿名對象的代碼,只需要 new 一個對象就行,而使用匿名對象的代碼,其實 new 了兩個對象
還有匿名對象只能在創(chuàng)建對象時使用,就是說創(chuàng)建匿名對象就要使用它
八、總結(jié)
最好我們再來鞏固幾個問題吧!
(1)引用一定在棧上嗎? 不一定
我們來看一段代碼
class Person{ private double age; private String name; private int[] elem = new int[10]; } public class Main{ public static void main(String[] args){ Person person = new Person(); } }
我們用一張圖來清晰感受下吧
其中 person是一個引用它在棧上,而 elem 是數(shù)組,它也是引用,可是它卻存放在堆中,所以引用不一定在棧上
(2)引用能指向引用嗎? 不能
之前就講過了,引用不能指向引用,這個說法不對。正確的說法應該是,該引用指向了另一個引用所指向的對象
一個引用可以指向多個對象嗎? 不能
(3)一個引用可以指向多個對象嗎? 不能
這不就是海王了嘛,比如 person 去找對象
Person person = new Person(); // person 先找了一個對象 person = new Person(); // 然后又找了一個 person = new Person(); // 牛逼!又找了一個 person = new Person(); // 佩服!還找了一個
你問 perosn 有幾個對象,我告訴你,就一個,而且還是最后一個,你問我為啥?海外必死
(4)一個引用賦值null 代表什么?
代表當前引用不指向任何對象
(5)你能用上述知識寫一個代碼實現(xiàn)交換兩個值嗎?
class Value{ private int val; public int getVal() { return val; } public void setVal(int val) { this.val = val; } } public class TestDemo{ public static void swap(Value val1, Value val2){ int tmp = val1.getVal(); val1.setVal(val2.getVal()); val2.setVal(tmp); } public static void main(String[] args) { Value value1 = new Value(); value1.setVal(10); Value value2 = new Value(); value2.setVal(20); System.out.println("交換前:value1 = " + value1.getVal() + " value2 = " + value2.getVal()); swap(value1,value2); System.out.println("交換前:value1 = " + value1.getVal() + " value2 = " + value2.getVal()); } } /**結(jié)果為: 交換前:value1 = 10 value2 = 20 交換前:value1 = 20 value2 = 10*/
到此這篇關(guān)于Java 基礎(chǔ)語法讓你弄懂類和對象的文章就介紹到這了,更多相關(guān)Java 基礎(chǔ)語法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
2020年IntelliJ IDEA最新最詳細配置圖文教程詳解
這篇文章主要介紹了2020年IntelliJ IDEA最新最詳細配置圖文教程詳解,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-02-02Spring gateway + Oauth2實現(xiàn)單點登錄及詳細配置
gateway是基于 WebFlux的響應式編程框架,所以在使用securityConfig時采用的注解是@EnableWebFluxSecurity,接下來通過本文給大家介紹Spring gateway + Oauth2實現(xiàn)單點登錄及詳細配置,感興趣的朋友一起看看吧2021-09-09SSH框架網(wǎng)上商城項目第29戰(zhàn)之使用JsChart技術(shù)顯示商品銷售報表
這篇文章主要為大家詳細介紹了SSH框架網(wǎng)上商城項目第29戰(zhàn)之使用JsChart技術(shù)顯示商品銷售報表,感興趣的小伙伴們可以參考一下2016-06-06Java String類詳解_動力節(jié)點Java學院整理
這篇文章主要介紹了Java String類詳解,本文經(jīng)多方資料的收集整理和歸納,最終撰寫成文,非常不錯,值得收藏,需要的的朋友參考下2017-04-04Spring中ResponseBodyAdvice的使用詳解
這篇文章主要介紹了Spring中ResponseBodyAdvice的使用,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-10-10SWT(JFace) Wizard(Eclipse插件編程必備)
SWT(JFace)小制作:Wizard(Eclipse插件編程必備)2009-06-06關(guān)于jdk環(huán)境變量配置以及javac不是內(nèi)部或外部命令的解決
這篇文章主要介紹了關(guān)于jdk環(huán)境變量配置以及javac不是內(nèi)部或外部命令的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-01-01