java基礎之枚舉和注解

枚舉

簡介

枚舉:enumeration,jdk1.5中引入的新特性,用于管理和使用常量

入門案例

第一步:定義枚舉,這里定義一個動物類,里面枚舉了多種動物

public enum AnimalEnum {CAT,  // 貓DOG,  // 狗PIG   // 豬
}

第二步:使用枚舉類,這里會打印枚舉類中的枚舉值

public static void main(String[] args) {// 打印枚舉類中的枚舉值System.out.println("AnimalEnum.CAT = " + AnimalEnum.CAT);  // CAT// 枚舉值的字符串形式,和它的聲明是一致的,可以把枚舉值當做一個字符串常量來使用System.out.println("AnimalEnum.CAT.toString().equals(\"CAT\") = " + AnimalEnum.CAT.toString().equals("CAT"));   // true
}

總結:可以把枚舉類中的枚舉值當做字符串常量去使用,入門案例中演示了枚舉類最基本的使用方式。

基本使用

語法

枚舉類中聲明的常量,本質上,是以枚舉類為數據類型的實例。

定義枚舉類的格式:

[訪問修飾符] enum <enum_name> {常量[(構造器參數)] [{  // 抽象方法的實現  }]  [, ....] [;]成員變量;構造方法;自定義方法;抽象方法;
}

從格式上看,枚舉類中可以定義構造方法、普通方法、抽象方法,因為枚舉類中聲明的常量本質上是以枚舉類為數據類型的實例,這些實例中可以存儲數據,也可以有自己的行為,不過在枚舉類中定義方法時在語法上有一些要求。

編寫枚舉類的語法要求:

  • 先定義枚舉值,后定義方法,枚舉值和方法之間用分號隔開。
  • 為枚舉類定義成員變量和構造方法:構造方法定義了枚舉值中可以存儲什么數據,構造方法默認被private修飾,所以用戶無需為構造方法指明訪問修飾符,這是為了防止枚舉類被外部實例化。
  • 為枚舉類定義普通方法:普通方法可以為枚舉值添加一些行為。
  • 為枚舉類定義抽象方法:枚舉類中可以聲明一個抽象方法,然后每個枚舉類的實例實現此抽象方法。枚舉類還可以實現某個接口,功能上類似于在枚舉類中定義抽象方法。

案例1:為枚舉類定義構造方法和普通方法

第一步:定義枚舉類

public enum ColorEnum {// 枚舉類中如果定義了構造方法,聲明枚舉值時要使用這個構造方法,它表示枚舉值中可以存儲的數據RED(1, "RED", "紅色"),BLUE(2, "BLUE", "藍色"),BLACK(3, "BLACK", "黑色");public Integer i;public String name;public String desc;// 構造方法ColorEnum(int i, String name, String desc) {this.i = i;this.name = name;this.desc = desc;}// 普通方法public void say() {System.out.println("我的顏色是:" + this.name);}
}

第二步:使用枚舉類

public static void main(String[] args) {// 1. 使用枚舉值System.out.println("ColorEnum.RED = " + ColorEnum.RED);  // ColorEnum.RED = RED// 2. 枚舉值中的普通方法ColorEnum.RED.say();  // 我的顏色是:RED
}

案例2:為枚舉類定義抽象方法

第一步:定義枚舉類

public enum OperationEnum {PLUS(1, "加法") {@Overridepublic double apply(double x, double y) {return x + y;}},MINUS (2, "減法") {@Overridepublic double apply(double x, double y) {return x - y;}};public final Integer id;public final String name;// 構造方法OperationEnum(Integer id, String name) {this.id = id;this.name = name;}// 聲明抽象方法public abstract double apply(double x, double y);
}

第二步:使用枚舉類

public static void main(String[] args) {// 枚舉類中的抽象方法double apply = OperationEnum.PLUS.apply(1, 2);System.out.println("apply = " + apply);  // 3
}

案例3:枚舉類實現接口

// 定義接口
public interface Inter {double apply(double a, double b);
}// 定義枚舉類
public enum Operation implements Inter {MINUS{public double apply(double a, double b){return a - b;}},PLUS{public double apply(double a, double b){return a + b;}};
}

使用方式和在枚舉類中定義抽象方法基本類型。

枚舉類的反編譯

枚舉類是一種特殊的類,枚舉類和普通類一樣,也會生成一個類文件,Java編譯器會為枚舉類添加許多方法。

案例:入門案例中的Animal類,使用javap命令來反編譯 javap -v AnimalEnum.class ,這里只展示反編譯后的部分結果。

// 枚舉類的底層繼承了Enum類
public final class org.wyj.enumeration.AnimalEnum extends java.lang.Enum<org.wyj.enumeration.AnimalEnum>
{public static final org.wyj.enumeration.AnimalEnum CAT;   // CATdescriptor: Lorg/wyj/enumeration/AnimalEnum;flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUMpublic static final org.wyj.enumeration.AnimalEnum DOG;   // DOGdescriptor: Lorg/wyj/enumeration/AnimalEnum;flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUMpublic static final org.wyj.enumeration.AnimalEnum PIG;   // PIGdescriptor: Lorg/wyj/enumeration/AnimalEnum;flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM// values方法,返回枚舉類中的所有實例public static org.wyj.enumeration.AnimalEnum[] values();descriptor: ()[Lorg/wyj/enumeration/AnimalEnum;flags: ACC_PUBLIC, ACC_STATICCode:stack=1, locals=0, args_size=00: getstatic     #1                  // Field $VALUES:[Lorg/wyj/enumeration/AnimalEnum;3: invokevirtual #2                  // Method "[Lorg/wyj/enumeration/AnimalEnum;".clone:()Ljava/lang/Object;6: checkcast     #3                  // class "[Lorg/wyj/enumeration/AnimalEnum;"9: areturnLineNumberTable:line 3: 0// valueOf方法,根據字符串常量來查找枚舉類實例public static org.wyj.enumeration.AnimalEnum valueOf(java.lang.String);descriptor: (Ljava/lang/String;)Lorg/wyj/enumeration/AnimalEnum;flags: ACC_PUBLIC, ACC_STATICCode:stack=2, locals=1, args_size=10: ldc           #4                  // class org/wyj/enumeration/AnimalEnum2: aload_03: invokestatic  #5                  // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;6: checkcast     #4                  // class org/wyj/enumeration/AnimalEnum9: areturnLineNumberTable:line 3: 0LocalVariableTable:Start  Length  Slot  Name   Signature0      10     0  name   Ljava/lang/String;
}

案例2:反編譯有抽象方法的枚舉類,javap -v OperationEnum.class

// 有抽象方法的枚舉類,枚舉類在底層實際上是一個抽象類
public abstract class org.wyj.enumeration.OperationEnum extends java.lang.Enum<org.wyj.enumeration.OperationEnum>
{public static final org.wyj.enumeration.OperationEnum PLUS;descriptor: Lorg/wyj/enumeration/OperationEnum;flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUMpublic static final org.wyj.enumeration.OperationEnum MINUS;descriptor: Lorg/wyj/enumeration/OperationEnum;flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
}

枚舉類中的每個枚舉值都會生成一個匿名內部類,javap -v "OperationEnum\$1.class",注意,這里美元符在命令行需要特殊處理

final class org.wyj.enumeration.OperationEnum$1 extends org.wyj.enumeration.OperationEnum
{// 構造方法org.wyj.enumeration.OperationEnum$1(java.lang.String, int, java.lang.Integer, java.lang.String);descriptor: (Ljava/lang/String;ILjava/lang/Integer;Ljava/lang/String;)Vflags:Code:stack=6, locals=5, args_size=50: aload_01: aload_12: iload_23: aload_34: aload         46: aconst_null7: invokespecial #1                  // Method org/wyj/enumeration/OperationEnum."<init>":(Ljava/lang/String;ILjava/lang/Integer;Ljava/lang/String;Lorg/wyj/enumeration/OperationEnum$1;)V10: returnLineNumberTable:line 5: 0LocalVariableTable:Start  Length  Slot  Name   Signature0      11     0  this   Lorg/wyj/enumeration/OperationEnum$1;0      11     3    id   Ljava/lang/Integer;0      11     4  name   Ljava/lang/String;// 實現父類中的抽象方法public double apply(double, double);descriptor: (DD)Dflags: ACC_PUBLICCode:stack=4, locals=5, args_size=30: dload_11: dload_32: dadd   // add命令,證明這是加法3: dreturnLineNumberTable:line 8: 0LocalVariableTable:Start  Length  Slot  Name   Signature0       4     0  this   Lorg/wyj/enumeration/OperationEnum$1;0       4     1     x   D0       4     3     y   D
}

總結:反編譯結果中枚舉類的成員,可以看到,

  • 枚舉類默認繼承了Enum類
  • 枚舉類中有兩個重要的靜態方法:
    • values():public static 枚舉類[] values();:返回枚舉類中所有常量組成的數組
    • valueOf(String):public static 枚舉類 valueOf(java.lang.String);:傳入枚舉類中常量的字符串形式,返回枚舉類中的常量
  • 聲明了抽象方法的枚舉類,枚舉類中的每個枚舉值都會使用一個匿名內部類來實現

枚舉類的默認父類 Enum類

所有的枚舉類都默認繼承了Enum類。

源碼分析:

public abstract class Enum<E extends Enum<E>>implements Comparable<E>, Serializable {// 枚舉值的字符串形式private final String name;public final String name() {return name;}// 表示枚舉值在枚舉類中被聲明的順序,從0開始計數private final int ordinal;public final int ordinal() {return ordinal;}// 構造方法protected Enum(String name, int ordinal) {this.name = name;this.ordinal = ordinal;}// 重寫Object類中的方法public String toString() {return name;}public final boolean equals(Object other) {return this==other;}public final int hashCode() {return super.hashCode();}protected final Object clone() throws CloneNotSupportedException {throw new CloneNotSupportedException();}// 兩個枚舉值的比較public final int compareTo(E o) {Enum<?> other = (Enum<?>)o;Enum<E> self = this;if (self.getClass() != other.getClass() && // optimizationself.getDeclaringClass() != other.getDeclaringClass())throw new ClassCastException();return self.ordinal - other.ordinal;}// 阻止反序列化private void readObject(ObjectInputStream in) throws IOException,ClassNotFoundException {throw new InvalidObjectException("can't deserialize enum");}private void readObjectNoData() throws ObjectStreamException {throw new InvalidObjectException("can't deserialize enum");}
}

枚舉值的默認父類幾乎不會被使用到,這里只做了解

實戰案例

案例1:switch和枚舉類

如果switch語句對應的變量是一個枚舉類的實例,case語句后必須直接使用枚舉類中的常量

案例:

public static void main(String[] args) {AnimalEnum DOG = AnimalEnum.DOG;switch (DOG) {case DOG:System.out.println("狗");  // 狗break;case PIG:System.out.println("豬");break;case CAT:System.out.println("貓");break;default:System.out.println("未知");break;}
}

案例2:生產中定義枚舉類的常見方式

public enum ColorEnum {// 枚舉類中如果定義了構造方法,聲明枚舉值是要使用這個構造方法,它表示枚舉值中可以存儲的數據RED(1, "RED", "紅色"),BLUE(2, "BLUE", "藍色"),BLACK(3, "BLACK", "黑色");public final Integer id;public final String name;public final String desc;// 構造方法ColorEnum(int id, String name, String desc) {this.id = id;this.name = name;this.desc = desc;}// 根據id獲取枚舉值實例public ColorEnum getEnumById(Integer id) {ColorEnum[] values = values();for (ColorEnum value : values) {if (value.id.equals(id)) {return value;}}return null;}// 返回枚舉值的集合public List<ColorEnum> getEnumList() {return Arrays.asList(values());}// 普通方法public void say() {System.out.println("我的顏色是:" + this.desc);}
}

這里需要注意的是,每個枚舉值都有自己的id和name,id用于數據庫的存儲,name用于平時使用,同時,定義了根據id來獲取枚舉值的方法,這是實際開發中用的最多的。

注解

簡介

注解:Annotation,Java1.5引入的功能,它可以被標注在類、方法、字段上,用于指明某種特性,也可以用它來存儲配置信息。

注解的使用,有兩種場景,

  • 一種是在源碼中,告訴程序員某個信息,例如@Override注解,告訴程序員當前方法是父類中某個方法的重寫,
  • 一種是在運行時,通過反射獲取注解信息,此時,注解可以用于存儲配置信息。

基本使用

java中的元注解

元注解:負責標注其它的注解,用于指明注解的特性,是用戶自定義注解是需要用到的

java中的5個元注解:

1、@Retention:指定注解的生命周期

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {RetentionPolicy value();  // 指定注解的生命周期
}

這里涉及到的兩個枚舉類:

a. 定義了注解的生命周期常量的枚舉類:

// 定義了注解有哪些生命周期
public enum RetentionPolicy {// 注解只存在于源碼中,會被編譯器丟掉。注解只存在于源碼階段SOURCE,// 注解會被編譯器編譯到類文件中,但是運行時不會把注解信息加載到虛擬機中,這是默認的生命周期。// 注解只存在于源碼階段和編譯階段CLASS,// 注解會被加載到虛擬機中,此時可以通過反射獲取注解中存儲的信息,// 注解存在于源碼階段、編譯階段和運行時階段RUNTIME
}

b. 定義了注解的使用位置常量的枚舉類:

// 枚舉類中的常量代表代表一個編譯單元中的某個位置
public enum ElementType {// 類、接口或枚舉TYPE,// 字段,包括枚舉常量FIELD,// 方法聲明METHOD,// 參數PARAMETER,// 構造器CONSTRUCTOR,// 局部變量LOCAL_VARIABLE,// 注解,一個可以應用于注解上的注解,類似于元注解。ANNOTATION_TYPE,// 包PACKAGE,// 表示注解可以應用于類型參數聲明,案例 public class MyClass<@MyAnnotation T> {}TYPE_PARAMETER,// 表示注解可以應用于類型使用的地方,例如變量聲明、方法返回類型、方法參數類型等TYPE_USE
}

2、@Documented:被@Documented注解的注解會被javadoc之類的工具處理,它們的信息會被添加到幫助文檔中,默認情況下,注解是不會被添加到幫助文檔中的。

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}

3、@Target:指明了注解可以出現在什么位置。默認情況下,枚舉可以被應用到除了泛型、包以外的任何地方

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {// 一個ElementType類型的數組,表明注解可以被應用在什么位置ElementType[] value();  
}

4、@Inherited:繼承。表示一個注解可以被繼承

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
}

5、@Repeatable:java1.8新增的注解,允許一個類型的注解在同一個程序元素上重復出現。

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Repeatable {// 指定哪個注解可以重復出現Class<? extends Annotation> value();
}

java中自帶的注解

1、@Override:只能用于方法,只存在于源碼階段,表明當前方法重寫了父類的方法。

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

2、@Deprecated:這個注解會被添加到文檔中,存在于運行階段,可以注解類、方法等。一個程序元素被@Deprecated注解,表明開發者不推薦用戶使用這個程序元素

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}

3、@SuppressWarnings:告訴編譯器忽略指定類型的告警,可以標注在類、字段、方法、局部變量等位置。

使用方式:

  • 告訴編譯器忽略類型轉換警告信息:@SuppressWarnings(“unchecked”)
  • 告訴編譯器忽略被過時告警:@SuppressWarnings(“deprecation”),使用了被@Deprecated標注的元素,編譯器會發出過時告警
  • 告訴編譯器同時忽略多個告警信息:
    • 第一種寫法:@SuppressWarnings(“unchecked”, “deprecation”)
    • 第二種寫法:@SuppressWarnings(value={“unchecked”, “deprecation”})
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {// 指定告警類型String[] value();
}

4、@FunctionalInterface:這個注解會被添加到文檔中,存在于運行階段,可以注解接口,表明被它注解的接口是一個函數式接口,也就是接口中只有一個方法的接口。

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FunctionalInterface {}

5、@SafeVarargs:這個注解會被添加到文檔中,存在于運行階段,可以注解構造器、方法。參數安全類型注解,它的目的是提醒開發者不要用參數做一些不安全的操作,它的存在會阻止編譯器產生 unchecked 這樣的警告。它是在 Java 1.7 的版本中加入的。

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD})
public @interface SafeVarargs {}

自定義注解

自定義注解的語法:

[public] @interface 注解名 { 參數類型 成員變量名() [default];....
}

語法講解:

  • 注解只有成員變量,沒有成員方法。
  • 聲明成員變量的格式:數據類型 成員變量名() [default 值]。成員變量可以有默認值,通過default關鍵字來指定。
  • 如果注解中只有一個屬性,那么屬性名稱應該為value,這是一個默認的約定。

注解的使用:把注解放在合適的位置,@注解名(屬性=值 [,...])

  • 如果注解中沒有屬性,那么括號可以省略不寫。
  • 如果屬性有默認值,那么在使用時就不需要為屬性賦值了如果想要覆蓋原有的屬性也可以賦值。
  • 如果屬性名是value,value可以省略不寫

注解的獲取:在運行階段,需要通過反射,獲取注解中的信息,如果想要讓注解被反射獲取,注解必須要被@Retention(RetentionPolicy.RUNTIME)注解,它表示注解的生命周期策略是運行時存在。

標記注解:不包含任何成員變量的注解

使用案例

案例1:自定義一個普通注解,指定一個類的初始化方法

第一步:定義注解

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface InitMethod {// 注解中存儲的數據,這里沒有什么意義,僅僅演示如何操作注解的屬性String value();String name() default "im";
}

第二步:使用注解,注解如果沒有指定使用范圍,默認可以使用在類上、方法上

public class InitDemo {public InitDemo() { }@InitMethod(value = "1", name = "2")public void test1(int b) {int a = 1;System.out.println("執行test1方法");}
}

第三步:通過反射獲取注解

public static void main(String[] args) {try {Class<?> aClass = Class.forName("org.wyj.anno.InitDemo");// 獲取類上的注解Annotation[] declaredAnnotations = aClass.getDeclaredAnnotations();for (Annotation declaredAnnotation : declaredAnnotations) {System.out.println("declaredAnnotation = " + declaredAnnotation);}// 獲取方法上的指定注解Method[] methods = aClass.getMethods();for (Method method : methods) {if (method.isAnnotationPresent(InitMethod.class)) {InitMethod annotation = method.getAnnotation(InitMethod.class);System.out.println(annotation);System.out.println(annotation.value() + ":" + annotation.name());}}} catch (ClassNotFoundException e) {throw new RuntimeException(e);}
}

總結:這個案例演示了注解的基本使用,實際開發中,這是使用最多的方式

案例2:可重復出現的注解

第一步:定義注解

// 可以重復使用的注解
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(Persons.class)   // 使用@Repeatable注解把當前注解定義為可重復注解時,要指定它的容器注解
public @interface Person {String role();
}// 注解的容器注解
@Retention(RetentionPolicy.RUNTIME)
public @interface Persons {Person[] value();
}

第二步:注解的使用

@Person(role = "藝術家")
@Person(role = "士兵")
@Person(role = "廚師")
public class Man {
}

第三步:通過反射獲取注解

// 測試容器注解
public static void main(String[] args) {try {Class<?> aClass = Class.forName("org.wyj.anno.Man");Person[] annotationsByType = aClass.getAnnotationsByType(Person.class);for (Person person : annotationsByType) {System.out.println(person.role());}} catch (ClassNotFoundException e) {e.printStackTrace();}
}

總結:

  • 在使用@Repeatable來注解一個可重復注解的時候,需要提供一個容器注解,容器注解用于裝載可重復注解。
  • 容器注解:@Repeatable注解需要使用到的工具注解,注解中的屬性是一個數組,數組中元素的數據類型是被@Repeatable注解的注解。

案例3:測試注解的繼承

第一步:定義注解,一個可以被繼承的注解

@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface InheritedTest {
}

第二步:注解的使用

// 父類
@InheritedTest
public class InheritedDemo {@InitMethod("aaa")public void init() { }
}// 子類
public class InheritedDemoSon extends InheritedDemo { }

第三步:通過反射獲取注解

public static void main(String[] args) {try {Class<?> aClass = Class.forName("org.wyj.anno.InheritedDemoSon");// 類上的注解System.out.println(aClass.isAnnotationPresent(InheritedTest.class)); // true// 方法上的注解for (Method method : aClass.getMethods()) {if (method.getName().equals("init")) {System.out.println("method.isAnnotationPresent(InitMethod.class) = "+ method.isAnnotationPresent(InitMethod.class));  // true}}} catch (ClassNotFoundException e) {throw new RuntimeException(e);}
}

總結:

  • 注解的繼承:在繼承關系中,
    • 對于方法上的注解,子類會繼承父類的方法,同時也會方法上的注解,無論該注解有沒有被@Inherited修飾,
    • 對于類上的注解,如果它被@Inherited注解修飾,它才可以被子類繼承,但也僅限于子類,不包括子類的子類

查看一個注解反編譯后的字節碼

案例:以@InitMethod為例,javap -v InitMethod.class

public interface org.wyj.anno.InitMethod extends java.lang.annotation.Annotation
{public abstract java.lang.String value();descriptor: ()Ljava/lang/String;flags: ACC_PUBLIC, ACC_ABSTRACTpublic abstract java.lang.String name();descriptor: ()Ljava/lang/String;flags: ACC_PUBLIC, ACC_ABSTRACT
}

總結:可以看到,注解實際上是一個接口,并且每個注解都默認繼承Annotation接口,

注解的公共父接口 Annotation接口

所有的注解默認都會繼承Annotation接口,這個動作由編譯器來完成

源碼:

public interface Annotation {boolean equals(Object obj);int hashCode();String toString();Class<? extends Annotation> annotationType();
}

總結

這里介紹了注解的基本特性,演示了注解的基本使用。如果有補充,歡迎評論。

Q&A

1、枚舉類的構造方法,為什么不可以是public?

由于枚舉實例是固定的,開發者不能在運行時創建新的枚舉實例。因此,構造方法不能是public的,Java編譯器自動將枚舉的構造方法設為private,以確保枚舉實例只能在枚舉類內部定義。這是為了確保枚舉實例的唯一性和安全性。

2、枚舉類可以同時是泛型類嗎?

不可以,枚舉類不可以是泛型類,但是枚舉類中可以定義泛型方法,因為枚舉類不可以從外部實例化,所以在枚舉類上聲明泛型沒有意義。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/78347.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/78347.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/78347.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

2.3java運算符

運算符 1. 算術運算符 算術運算符用于執行基本的數學運算&#xff0c;像加、減、乘、除等。 運算符描述示例加法int a 5 3; // a 的值為 8-減法int b 5 - 3; // b 的值為 2*乘法int c 5 * 3; // c 的值為 15/除法int d 6 / 3; // d 的值為 2%取模&#xff08;取余&…

升級 Spring Boot CLI

&#x1f31f; 升級 Spring Boot CLI 1?? &#x1f504; 通過包管理器升級 使用對應包管理器命令&#xff08;如 brew upgrade&#xff09; 2?? &#x1f4e5; 手動安裝升級 遵循 標準安裝說明 注意更新 PATH 環境變量移除舊版本路徑 &#x1f517; 鏈接原文&#xff1a…

如何輕松將RS232轉為Profibus DP,提升PLC效率?

如何輕松將RS232轉為Profibus DP&#xff0c;提升PLC效率&#xff1f; 今天&#xff0c;我們就來聊聊一個工業自動化中常見的應用場景&#xff1a;如何通過興達易控RS232轉Profibus DP網關&#xff0c;實現流量泵與PLC&#xff08;可編程邏輯控制器&#xff09;的通信。這個話…

QT 連接數據庫操作(15)

文章目錄 一、本章說明二、QT連接云端數據庫實現2.1 ODBC軟件安裝及參數設置2.2 軟件代碼實現三、項目源碼文件一、本章說明 注:本節為【基于STM的環境監測系統(節點+云服務器存儲+QT界面設計)】項目第15篇文章,前面已經創建了監測軟件的登錄窗口,接下來我們將在主窗口實…

linux系統之----命令行參數和環境變量

一、命令行參數 1.main()函數的參數 在C語言中&#xff0c;main函數可以接收命令行參數&#xff0c;其標準形式為&#xff1a; int main(int argc, char *argv[]) {// 程序代碼return 0; } 這里我們解釋一下&#xff1a; argc&#xff1a;參數個數計數器&#xff08;Argum…

解析excel中的圖片

解析excel中的圖片 前言一、pom依賴二、使用步驟1.示例數據2.代碼如下&#xff08;示例&#xff09;&#xff1a; 總結 前言 初始化數據是&#xff0c;需要將excel中的數據解析并插入數據庫。 但是某幾列存放的是圖片&#xff0c;這時候怎么辦呢。 主要解決的是&#xff1a;獲…

Unity任務系統筆記

數據結構設計 任務基類包括的字段&#xff1a; string 任務內容&#xff1b; Transform 任務目的地&#xff1b; MyCharacter 任務開啟后要更新對話的NPC&#xff1b; MyTalkData 任務開啟后相關NPC要說的對話數據&#xff1b; 共同方法&#xff1a;開啟任務、完成任務。…

STM32的開發環境介紹

目錄 STM32軟件環境 Keil軟件在線安裝 其他軟件環境安裝 STM32開發的幾種方式 STM32寄存器版本和庫函數版本 標準外設庫的作用&#xff1a; STM32軟件環境 STM32 的集成開發環境&#xff08;IDE&#xff09;&#xff1a;編輯編譯軟件 常見的環境&#xff1a; (1)KEIL&a…

【特殊場景應對9】視頻簡歷的適用場景與風險分析

寫在最前 作為一個中古程序猿,我有很多自己想做的事情,比如埋頭苦干手搓一個低代碼數據庫設計平臺(目前只針對寫java的朋友),比如很喜歡幫身邊的朋友看看簡歷,講講面試技巧,畢竟工作這么多年,也做到過高管,有很多面人經歷,意見還算有用,大家基本都能拿到想要的offe…

Linux系統性能調優技巧分享

在數字化時代,Linux 系統以其開源、穩定、高效的特性,成為服務器、云計算、物聯網等領域的核心支撐。然而,隨著業務規模的擴大和負載的增加,系統性能問題逐漸凸顯。掌握 Linux 系統性能調優技巧,不僅能提升系統運行效率,還能降低運維成本。下面從多個方面介紹實用的性能調…

關于Code_流蘇:商務合作、產品開發、計算機科普、自媒體運營,一起見證科技與藝術的交融!

Code_流蘇 &#x1f33f; 名人說&#xff1a;路漫漫其修遠兮&#xff0c;吾將上下而求索。—— 屈原《離騷》 創作者&#xff1a;Code_流蘇(CSDN)&#xff08;一個喜歡古詩詞和編程的Coder&#x1f60a;&#xff09; &#x1f31f; 歡迎來到Code_流蘇的CSDN主頁 —— 與我一起&…

系統架構設計(三):質量屬性

常見分類 一般來說&#xff0c;質量屬性可以分為以下幾類&#xff1a; 類別常見質量屬性性能相關響應時間、吞吐量、資源利用率、實時性、可擴展性可用性相關可用性、高可用性&#xff08;HA&#xff09;、可靠性、容錯性、恢復性可維護性相關可維護性、可測試性、可擴展性、…

【鋰電池剩余壽命預測】GRU門控循環單元鋰電池剩余壽命預測(Matlab完整源碼)

目錄 效果一覽程序獲取程序內容代碼分享研究內容GRU門控循環單元在鋰電池剩余壽命預測中的應用摘要關鍵詞1. 引言1.1 研究背景1.2 研究現狀與問題1.3 研究目的與意義2. 文獻綜述2.1 鋰電池剩余壽命預測傳統方法2.2 深度學習在鋰電池壽命預測中的應用2.3 研究空白與本文切入點3.…

SpringCloud原理和機制

Spring Cloud 是一套基于Spring Boot的微服務開發工具集&#xff0c;它提供了在分布式系統環境下構建應用程序所需的一系列工具和服務。Spring Cloud旨在幫助開發人員快速構建一些常見的微服務模式&#xff0c;如服務發現、配置管理、智能路由、熔斷器、微代理、控制總線等。 …

LeetCode -- Flora -- edit 2025-04-25

1.盛最多水的容器 11. 盛最多水的容器 已解答 中等 相關標簽 相關企業 提示 給定一個長度為 n 的整數數組 height 。有 n 條垂線&#xff0c;第 i 條線的兩個端點是 (i, 0) 和 (i, height[i]) 。 找出其中的兩條線&#xff0c;使得它們與 x 軸共同構成的容器可以容納最…

有關圖的類型的題目以及知識點(2)

1、具有5個頂點的有向完全圖有20條弧。 2、若一個有向圖用鄰接矩陣表示&#xff0c;則第個結點的入度就是&#xff1a;第i列的非零元素的個數。 3、有向圖的鄰接矩陣可以是對稱的&#xff0c;也可以是不對稱的。 4、設N個頂點E條邊的圖用鄰接表存儲&#xff0c;則求每個頂點…

正則表達式的捕獲組

是正則表達式中的一個重要概念&#xff0c;用于提取字符串中的特定部分 捕獲組是通過正則表達式中的圓括號 () 定義的&#xff0c;它的作用是&#xff1a; 劃分和標記&#xff1a;將正則表達式的一部分劃分為邏輯單元。 提取數據&#xff1a;從字符串中提取符合組內模式的內容…

deepseek-cli開源的強大命令行界面,用于與 DeepSeek 的 AI 模型進行交互

一、軟件介紹 文末提供程序和源碼下載 deepseek-cli一個強大的命令行界面&#xff0c;用于與 DeepSeek 的 AI 模型進行交互。 二、Features 特征 Multiple Model Support 多模型支持 DeepSeek-V3 (deepseek-chat) DeepSeek-R1 &#xff08;deepseek-reasoner&#xff09;Dee…

Java—— 五道算法水題

第一題 需求&#xff1a; 包裝類&#xff1a;鍵盤錄入一些1~100之間的整數&#xff0c;并添加到集合中。直到集合中所有數據和超過200為止 代碼實現&#xff1a; import java.util.ArrayList; import java.util.Scanner;public class Test1 {public static void main(String[]…

安全編排自動化與響應(SOAR):從事件響應到智能編排的技術實踐

安全編排自動化與響應&#xff08;SOAR&#xff09;&#xff1a;從事件響應到智能編排的技術實踐 在網絡安全威脅復雜度指數級增長的今天&#xff0c;人工處理安全事件的效率已難以應對高頻攻擊&#xff08;如日均萬級的惡意IP掃描&#xff09;。安全編排自動化與響應&#xf…