網站首頁 編程語言 正文
Object類
Dart中所有的東西都是對象,所有的對象都繼承自Object類.
普通類的聲明
特點:用new關鍵字實例化
class Class01{
//變量
int a;
String b;
var c=3;
//函數
void fun01(int d){
}
String fun2(){
return b;
}
}
void main(){
//記住練習類要在main函數外面創建,里面會報錯
var class01= new Class01();
print(class01.c);//3
class01..a=1..b="b";//..級聯操作符可以連續調用類的屬性進行賦值
print(class01.a);//1
print(class01.b);//'b'
}
類屬性和類方法(也叫靜態屬性和靜態方法)
特點:使用static關鍵字來聲明
main(List<String> args) {
// static關鍵字聲明的類屬性和類方法不用實例直接可以使用類名點的方法來調用.
Person.courseTime = "8:00";
print(Person.courseTime); //8:00
Person.gotoCourse();//去上課
}
class Person {
// 成員變量
String name;
// 靜態屬性(類屬性)
static String courseTime;
// 對象方法
void eating() {
print("eating");
}
// 靜態方法(類方法)
static void gotoCourse() {
print("去上課");
}
}
默認構造函數
class Class02{
//變量
int a =3;
//未聲明構造函數,有下面默認構造函數
Class2(){}
}
void main (){
var class02=new Class02();//正常實例化
print(class02.a);//3
}
自定義構造函數
class Class03{
int a;
String b;
// 自定義構造函數
Class03(int a,String b){
this.a=a;
this.b=b;
}
}
void main (){
var class03=new Class03(1, "a");
print(class03.a);//1
print(class03.b);//a
}
上面簡寫
class Class03{
int a;
String b;
// 自定義構造函數簡寫
Class03(this.a,this.b);
}
void main (){
var class03 =new Class03(1, "a");
print(class03.a);//1
print(class03.b);//a
}
命名構造函數
其實就是一種可以為類聲明多個不同的構造函數.
class Class03{
int a;
String b;
Class03(int a,String b){
this.a=a;
this.b=b;
}
Class03.fun1(int a){
this.a=a;
}
Class03.fun2(String b){
this.b=b;
}
}
void main (){
var class03=new Class03(4, "d");
var class04=new Class03.fun1(5);
var class05=new Class03.fun2('d');
print(class04.a);//5
print(class05.b);//'d'
}
靜態構造函數(也叫常量構造函數)
特點:
1.用final關鍵字修飾變量,
2.用const修飾構造函數,
3.實例化使用的是const關鍵字(并不是new關鍵字)
4.可以創建相同的對象.
class Class04{
// 用final修飾常量
final int a;
final String b;
// 用const 修飾構造函數
const Class04(this.a,this.b);
//普通函數
void fun01(){
print("aa");
}
}
void main (){
var class04=const Class04(1, "a");
print(class04.a);//1
class04.fun01();//aa
}
main(List<String> args) {
var p1 = const Person('why');//賦值時const關鍵字可以省略
var p2 = const Person('why');
print(identical(p1, p2)); // true
}
class Person {
final String name;
const Person(this.name);
}
重定向構造函數
class Class05{
int a;
String b;
Class05(int a,String b){
this.a=a;
this.b=b;
}
Class05.fun1(int a){
this.a=a;
}
// 重定向構造函數
Class05.fun2(String b):this.fun1(33);//重定向到函數fun1
Class05.fun3(String b):this(33,"ccc");//重定向到構造函數Class05
}
void main (){
var class05 =new Class05(55, "fff");
print(class05.a);//55
var class06=new Class05.fun2("hhh");
print(class06.a);//33,被重定向到了fun1
var class07=new Class05.fun3("hhh");
print(class07.a);//33,被重定向到了構造函數Class05
print(class07.b);//ccc,被重定向到了構造函數Class05
工廠構造函數
特點:
1.使用facory關鍵字聲明構造函數;
2.跟普通構造函數區別,在factory構造函數里需要手動return一個對象;
class Class06 {
int a;
static Class06 instance; //這里用static關鍵字創建一個單例
factory Class06(int a) {
//這里的構造函數用factory修飾,使用new時,不再是創建一個全新的實例了,而是通過函數體內return獲取到實例
if (instance == null) {
instance = new Class06.fun1(a);
}
return instance;
}
Class06.fun1(this.a); //這里是實例化當前對象的構造方法
}
void main() {
var class06 = new Class06(22);
var class07 = new Class06(22);
print(class06.a); //22
print(identical(class06, class07)); //true,通過工廠構造函數創建出來的是同一個對象
}
工廠函數創建相同對象的案例:
main(List<String> args) {
final p1 =
Person.withName("why"); //依次打印:沒對象創建一個null;{};name=why color=default
final p2 = Person.withName("why");//打印:有對象后: {why: name=why color=default}
print(identical(p1, p2)); //true
}
// 常量構造方法創建同一個對象的局限只能限定一個構造函數
// class Person {
// final String name;
// final String color = "red";
// const Person(this.name);
// const Person(this.color);
// }
// 而工廠函數創建同一個對象可以創建不同的構造函數
// 比如下面的需求:如果傳入的name相同則返回相同的對象;如果傳入的color相同,也可以返回相同的對象
// 普通的構造函數: 會自動返回創建出來的對象, 不能手動的返回
// 工廠構造函數最大的特點: 可以手動的返回一個對象
class Person {
String name;
String color;
static final Map<String, Person> _nameCache = {};
static final Map<String, Person> _colorCache = {};
factory Person.withName(String name) {
if (_nameCache.containsKey(name)) {
print('有對象后: $_nameCache'); //{why: name=why color=default}
return _nameCache[name];
} else {
final p = Person(name, "default");
print('沒對象創建一個${_nameCache[name]}'); //null
print(_nameCache); //{}
print(p); //實質是對象,打印name=why color=default
_nameCache[name] = p;
return p;
}
}
@override
String toString() {
return 'name=$name color=$color';
}
factory Person.withColor(String color) {
if (_colorCache.containsKey(color)) {
return _colorCache[color];
} else {
final p = Person("default", color);
_colorCache[color] = p;
return p;
}
}
Person(this.name, this.color);
}
get 和 set 修飾詞的應用
class Rect{
num height;
num width;
Rect(this.height,this.width);
get area{//注意get這里是類
return this.height*this.width;
}
set areaHeight(value){//set是設置方法
this.height=value;
}
}
void main(){
Rect r=new Rect(10,4);
print("面積:${r.area}"); //10*4=40,所以輸出40.注意調用直接通過訪問屬性的方式訪問area,如果調用括號會報錯
r.areaHeight=6;//注意設置也是直接通過實例.方法名的方式設置
print(r.area);//輸出24
}
可以用箭頭函數簡寫:
main(List<String> args) {
final p = Person();
// 通過getter和setter訪問
p.setName = "lilei";
print(p.getName);
}
class Person {
String name;
// 常規set和get寫法
// set setName(String name) {
// this.name = name;
// }
// get getName {
// //記住這里是大括號
// return name;
// }
// 箭頭函數簡寫
set setName(String name) => this.name = name;
String get getName => name;
}
抽象方法
特點:
-
1、抽象類通過abstract 關鍵字來定義
-
2、Dart中的抽象方法不能用abstract聲明,Dart中沒有方法體的方法我們稱為抽象方法。
-
3、如果子類繼承抽象類必須得實現里面的抽象方法
-
4、如果把抽象類當做接口實現的話必須得實現抽象類里面定義的所有屬性和方法。
-
5、抽象類不能被實例化,只有繼承它的子類可以
//定義抽象類,使用abstract修飾
abstract class Class09{
void fun01();//這里是定義抽象方法
}
//繼承抽象類
class Class10 extends Class09 {
@override
void fun01(){//這里是實現抽象方法
print("定義自己的抽象方法");
}
}
void main(){
var class10=new Class10();
class10.fun01();//打印:定義自己的抽象方法
}
案例:
定義一個Animal 類要求它的子類必須包含eat方法
abstract class Animal{
eat(); //抽象方法
run(); //抽象方法
printInfo(){
print('我是一個抽象類里面的普通方法');
}
}
class Dog extends Animal{
@override
eat() {
print('小狗在吃骨頭');
}
@override
run() {
// TODO: implement run
print('小狗在跑');
}
}
class Cat extends Animal{
@override
eat() {
// TODO: implement eat
print('小貓在吃老鼠');
}
@override
run() {
// TODO: implement run
print('小貓在跑');
}
}
main(){
Dog d=new Dog();
d.eat();//小狗在吃骨頭
d.printInfo();//我是一個抽象類里面的普通方法
Cat c=new Cat();
c.eat();//小貓在吃老鼠
c.printInfo();//我是一個抽象類里面的普通方法
// Animal a=new Animal(); //報錯,抽象類沒法直接被實例化
}
接口
特點:使用implements關鍵字
/*
定義一個DB庫 支持 mysql mssql
mysql mssql 兩個類里面都有同樣的方法
*/
abstract class Db{ //當做接口 接口:就是約定 、規范
String uri; //數據庫的鏈接地址
add(String data);
save();
delete();
}
class Mysql implements Db{
@override
String uri;
Mysql(this.uri);
@override
add(data) {
// TODO: implement add
print('這是mysql的add方法'+data);
}
@override
delete() {
// TODO: implement delete
return null;
}
@override
save() {
// TODO: implement save
return null;
}
remove(){
}
}
class MsSql implements Db{
@override
String uri;
MsSql(this.uri);
@override
add(String data) {
print('這是mssql的add方法'+data);
}
@override
delete() {
// TODO: implement delete
return null;
}
@override
save() {
// TODO: implement save
return null;
}
}
main() {
Mysql mysql=new Mysql('xxxxxx');
mysql.add('1243214');//這是mysql的add方法1243214
MsSql mssql=new MsSql('xxxxxx');
mssql.add('1243214');//這是mssql的add方法1243214
}
案例2
特點:
比如下面 Impostor 實現了類Person ,那么Impostor 中必須重寫Person 中所有的屬性和函數。
// person 類。 隱式接口里面包含了 greet() 方法聲明。
class Person {
// 包含在接口里,但只在當前庫中可見。
final _name;
// 不包含在接口里,因為這是一個構造函數。
Person(this._name);
// 包含在接口里。
String greet(String who) => 'Hello, $who. I am $_name.';
}
// person 接口的實現。
class Impostor implements Person {
@override
get _name => '';
@override
String greet(String who) => 'Hi $who. Do you know who I am?';
}
//聲明greetBob函數
String greetBob(Person person) => person.greet('Bob');
void main() {
print(greetBob(Person('Kathy')));//Hello, Bob. I am Kathy.
print(greetBob(Impostor()));//Hi Bob. Do you know who I am?
}
extends抽象類 和 接口implements 的區別:
-
1、如果要復用抽象類里面的方法,并且要用抽象方法約束子類的話我們就用extends繼承抽象類
-
2、如果只是把抽象類當做標準的話我們就用接口implements實現抽象類.
接口案例:
// Dart中沒有哪一個關鍵字是來定義接口的, 沒有這些關鍵字interface/protocol
// 默認情況下所有的類都是隱式接口
// Dart支持單繼承
// 當將一個類當做接口使用時, 那么實現這個接口的類, 必須實現這個接口中所有方法(即里面都要重寫接口里的方法)
class Runner {
void running() {
}
}
class Flyer {
void flying() {
}
}
class Animal {
void eating() {
print("動物次東西");
}
void running() {
print("running");
}
}
// 在接口里要必須重新實現接口里的方法
class SuperMan extends Animal implements Runner, Flyer {//這里不但繼承Animal類,因為已經有running方法了,所以接口里面可以不用寫running了,
@override
void eating() {
super.eating();
}
@override
void flying() {
}
}
多態(實際是抽象類)
特點:
- 用abstract關鍵字
- 子類的實例賦值給父類的引用。
- 多態就是父類定義一個方法不去實現,讓繼承他的子類去實現,每個子類有不同的表現。
abstract class Animal{
eat(); //抽象方法
}
class Dog extends Animal{
@override
eat() {
print('小狗在吃骨頭');
}
run(){
print('小狗run');
}
}
class Cat extends Animal{
@override
eat() {
print('小貓在吃老鼠');
}
run(){
print('小貓run');
}
}
main(){
//普通實例化和調用
// Dog d=new Dog();
// d.eat();//小狗在吃骨頭
// d.run();//小狗run
// Cat c=new Cat();
// c.eat();//小貓在吃老鼠
// c.run();//小貓run
//多態的使用:子類的實例賦值給父類的引用;多態就是父類定義一個方法不去實現,讓繼承他的子類去實現
Animal d=new Dog();
d.eat();//小狗在吃骨頭
Animal c=new Cat();
c.eat();//小貓在吃老鼠
}
靜態變量和靜態函數的使用
class Class11{
static int a=3;//靜態變量
int b=4;//實例變量
static void fun01(int c){//靜態方法
print(c);
}
void fun02(){//實例方法
print(this.b);
}
}
void main (){
var class11=new Class11();
print(class11.b);//4,實例變量
print(Class11.a);//3,靜態變量
class11.fun02();//4 ,實例函數調用
Class11.fun01(44);//44 靜態函數調用
}
枚舉類型
特點:使用enum修飾類,每個枚舉值都有一個唯一值,不用實例化,直接枚舉名點values獲取所有枚舉值.
//定義枚舉
enum Week { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday }
void main() {
List<Week> list = Week.values; //values屬性獲取所有枚舉值
print(
list); //[Week.Monday, Week.Tuesday, Week.Wednesday, Week.Thursday, Week.Friday, Week.Saturday, Week.Sunday]
list.forEach((e) {
print(e); //依次如下打印
// Week.Monday
// Week.Tuesday
// Week.Wednesday
// Week.Thursday
// Week.Friday
// Week.Saturday
// Week.Sunday
print(e.index);//依次如下打印
// 0
// 1
// 2
// 3
// 4
// 5
// 6
});
}
類實例化對象的操作符
? 條件運算符 (了解)
as 類型轉換
is 類型判斷
.. 級聯操作 (連綴) (很常見)
class Person {
String name;
num age;
Person(this.name, this.age);
void printInfo() {
print("${this.name}---${this.age}");
}
}
void main() {
// ?運算符
Person p;
print(p); //null
p?.printInfo(); //沒執行后面方法.這是條件運算符判斷,如果?前面是空,則不會執行后面操作
Person p = new Person("張三", 18);
p?.printInfo(); //張三---18
// is運算符
Person p = new Person("張三", 18);
if (p is Person) {
//is判斷是否是后面的類型
p.name = "李四";
}
p.printInfo(); //李四---18
Person p = new Person("張三", 18);
print(p is Object); //true
// ..運算符
Person p = new Person("張三", 18);
// 等同于
p
..name = "李四"
..age = 30
..printInfo(); //李四---30
}
繼承
簡單繼承
class Person {
String name='張三';
num age=20;
void printInfo() {
print("${this.name},${this.age}");
}
}
class Web extends Person{
}
main(){
Web w=new Web();
print(w.name);//張三
w.printInfo();//張三,20
}
super關鍵字的使用
子類給父類傳參
class Person {
String name;
num age;
Person(this.name,this.age);
void printInfo() {
print("${this.name}---${this.age}");
}
}
class Web extends Person{
// Web(String name, num age) : super(name, age){//這里是子類給父類傳參
// }
// 可以簡寫
Web(String name, num age) : super(name, age);
}
main(){
Web w=new Web('張三', 12);
w.printInfo();//張三---12
}
給子類添加自己的屬性
class Person {
String name;
num age;
Person(this.name,this.age);
void printInfo() {
print("${this.name}---${this.age}");
}
}
class Web extends Person{
String sex;
Web(String name, num age,String sex) : super(name, age){
this.sex=sex;
}
run(){
print("${this.name}---${this.age}--${this.sex}");
}
}
main(){
Web w=new Web('張三', 12,"男");
w.printInfo();//張三---12
w.run();//張三---12--男
}
子類給父類命名構造函數傳參
class Person {
String name;
num age;
Person(this.name,this.age);
Person.xxx(this.name,this.age);
void printInfo() {
print("${this.name}---${this.age}");
}
}
class Web extends Person{
String sex;
Web(String name, num age,String sex) : super.xxx(name, age){
this.sex=sex;
}
run(){
print("${this.name}---${this.age}--${this.sex}");
}
}
main(){
Web w=new Web('張三', 12,"男");
w.printInfo();//張三---12
w.run();//張三---12--男
}
子類覆寫父類的方法
class Person {
String name;
num age;
Person(this.name,this.age);
void printInfo() {
print("${this.name}---${this.age}");
}
work(){
print("${this.name}在工作...");
}
}
class Web extends Person{
Web(String name, num age) : super(name, age);
run(){
print('run');
}
//覆寫父類的方法
@override //可以寫也可以不寫 建議在覆寫父類方法的時候加上 @override
void printInfo(){
print("姓名:${this.name}---年齡:${this.age}");
}
@override
work(){
print("${this.name}的工作是寫代碼");
}
}
main(){
Web w=new Web('李四',20);
w.printInfo();//姓名:李四---年齡:20
w.work();//李四的工作是寫代碼
}
子類里面調用父類的方法
class Person {
String name;
num age;
Person(this.name,this.age);
void printInfo() {
print("${this.name}---${this.age}");
}
work(){
print("${this.name}在工作...");
}
}
class Web extends Person{
Web(String name, num age) : super(name, age);
run(){
print('run');
super.work(); //自類調用父類的方法
}
//覆寫父類的方法
@override //可以寫也可以不寫 建議在覆寫父類方法的時候加上 @override
void printInfo(){
print("姓名:${this.name}---年齡:${this.age}");
}
}
main(){
Web w=new Web('李四',20);
w.printInfo();//姓名:李四---年齡:20
w.run();//run 李四在工作...
}
繼承案例:
main(List<String> args) {
var p = new Person('why', 18);
print(p); //打印:name=why, age=18
p.run(); //打印:why在奔跑ing
}
class Animal {
int age;
Animal(this.age);
run() {
print('在奔跑ing');
}
}
class Person extends Animal {
String name;
Person(String name, int age)
: this.name = name, //這里是將傳遞過來的name賦值給name,this可以省略,后面使用逗號
super(age);
@override
run() {
print('$name在奔跑ing');
}
// 重寫Person的toString方法
@override
String toString() {
return 'name=$name, age=$age';
}
}
mixins多類繼承
如果繼承已經寫好的多接口方法不想重寫的話,直接用mixin混入就不用每個方法重寫一遍了.
特點:
1.用mixin/class關鍵字來聲明類接口規范;
2.用with關鍵字來混入引用;
3.混入的類中可以不用重寫mixin中的方法;
案例1
main(List<String> args) {
final sm = SuperMan();
sm.running(); //SuperMan running
sm.flying(); //flying
}
mixin Runner {
//這里不使用class關鍵字,使用mixin代替class
void running() {
print("runner running");
}
}
mixin Flyer {
void flying() {
print("flying");
}
}
class Animal {
void eating() {
print("動物次東西");
}
void running() {
print("animal running");
}
}
class SuperMan extends Animal with Runner, Flyer {//使用with混入已經寫好的Runner Flyer類
@override
void eating() {
super.eating();
}
void running() {
print("SuperMan running");
}
}
調用順序總結:自己有的方法直接調用自己的,然后再找繼承的,再沒有的會找混入的mixin方法.
案例2
class With1 {//用mixin關鍵字來代替class也是一樣的
String getName() => 'With1';//三個類都有該方法
String getAge()=> "With1 10" ;//該類獨有
}
class With2 {用mixin關鍵字來代替class也是一樣的
String getName() => 'With2';//三個類都有該方法
String getColor() => "With2 red";//該類獨有
int getNum()=> 6;//該類和OtherClass都有
String getFruit()=>"With2 banana";
}
class OtherClass {
String getName() => 'OtherClass';//三個類都有該方法
int getNum() => 3; //該類和With2都有
int getDesk() => 333;//該類獨有
String getPhone()=>"OtherClass huawei";//該類和子類
String getFruit()=>"OtherClass apple";
}
class Child1 extends OtherClass with With1 ,With2 {
//重寫父類
@override
String getPhone() {
return "Child1 iphone";
}
@override
String getFruit() {
return "Child1 oriange";
}
}
class Child2 extends OtherClass with With2, With1 {}
void main(){
print("class Child1 extends OtherClass with With1 ,With2 {}");
Child1 c1 = Child1();
print(c1.getPhone());//Child1 iphone 重寫了函數,調用時用的是自身的函數
print(c1.getFruit());//Child1 oriange 重寫了函數,調用時用的是自身的函數
print(c1.getDesk());//333 調用的是OtherClass的函數 With1 With2中沒有同名函數
print(c1.getNum());//6 調用的是With2中的函數
print(c1.getAge());//With1 10 調用的是With1中的函數
print(c1.getColor());//With2 red 調用的是With2中的函數
print(c1.getName());//With2 調用的是With2中的函數 With2在聲明順序中更靠后
print("-----------------------");
print("class Child2 extends OtherClass with With2, With1 {}");
Child2 c2 = Child2();
print(c2.getPhone());//OtherClass huawei 沒有重寫函數,調用時用的是OtherClass的函數
print(c2.getFruit());//With2 banana 沒有重寫函數,調用時用的是With2的函數,雖然OtherClass也有,但With2在聲明順序中更靠后
print(c2.getDesk());//333 調用的是OtherClass的函數 With1 With2中沒有同名函數
print(c2.getNum());//6 調用的是With2中的函數
print(c2.getAge());//With1 10 調用的是With1中的函數
print(c2.getColor());//With2 red 調用的是With2中的函數
print(c2.getName());//With1 調用的是With1中的函數 With1在聲明順序中更靠后
}
解釋說明:
-
A extends B with C,D{}。
-
A 繼承了B 并擁有了C和D所有的屬性和函數,可以用A的實例直接調用CD的屬性方法。
-
如果B有函數fun1,A重寫了這個函數 那么以后A的實例調用的fun1,都是A重寫后的方法。
-
如果B有函數fun1,CD中也有函數fun1,A重寫了這個函數 那么以后A的實例調用的fun1,都是A重寫后的方法。
-
如果B有函數fun1,CD中也有函數fun1,A沒有重寫這個函數 那么以后A的實例調用的fun1,是聲明方法時最后的那個類的函數,比如“A extends B with C,D”,那么就是D中的fun1,如果是“A extends B with D,C”,那么就是C中的fun1。也就是說優先級是從后向前的(前提是子類沒有重寫函數)。
枚舉
枚舉是一種特殊的類, 通常用于表示固定數量的常量值.
特點:
1.使用enum關鍵字來進行定義類;
2.不能拿來實例化;
main(List<String> args) {
print(Colors.red); //Colors.red
}
enum Colors { red, green, blue }
枚舉中兩個常見的屬性:
-
index: 用于表示每個枚舉常量的索引, 從0開始.
-
values: 包含每個枚舉值的List;
main(List<String> args) {
// 屬性index
print(Colors.red.index);//0
print(Colors.green.index);//1
print(Colors.blue.index);//2
// 屬性values
print(Colors.values);//打印:[Colors.red, Colors.green, Colors.blue]
}
常見枚舉的用法:
// 枚舉用法
main(List<String> args) {
final color = Colors.red;
switch (color) {
case Colors.red:
//todo
print("紅色");
break;
case Colors.blue:
print("藍色");
break;
case Colors.green:
print("綠色");
break;
}
}
enum Colors {
red,
blue,
green
}
原文鏈接:https://blog.csdn.net/xiaodi520520/article/details/107521198
相關推薦
- 2023-03-02 C++版本基于ros將文件夾中的圖像轉換為bag包_C 語言
- 2022-08-10 etcd通信接口之客戶端API核心方法實戰_Golang
- 2022-12-03 FFmpeg?Principle分析Out?put?File?數據結構_Android
- 2023-07-02 Linux系統下如何實現修改主機名_Linux
- 2021-12-06 Redis限流的幾種實現_Redis
- 2022-07-16 CMake下調用anaconda的pytorch及numpy傳參CV::Mat給python(多線程
- 2022-05-24 Django框架基礎認證模塊auth應用示例_python
- 2022-07-18 python中數組array和列表list的基本用法及區別解析_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支