主頁 > 後端開發 > 框架的靈魂之注解基礎篇

框架的靈魂之注解基礎篇

2021-04-13 10:59:34 後端開發

學習不是挖掘某人潛力的方式,而是發展這種潛力的方式,

有目錄, 不迷路

  • 什么是注解?
  • 注解的作用
  • 內置注解
    • @Override
    • @Deprecated
    • @SuppressWarnings
  • 元注解
    • @Target
    • @Retention
  • 自定義注解
  • 尾聲

什么是注解?

注解(Annotation),又稱作元資料,翻開之前我寫過關于Java語言發展史的博客:那些年Java走過的路,找到其中的<Java語言發展狀況>章節便可知,它是屬于JDK5.0引入的技術,距今已有17年歷史了,可見他還是個少年,或許他也曾夢想仗劍走天涯,可惜bug多沒去,

在這里插入圖片描述

在這里插入圖片描述
說起注解,大家可能會想到詞匯表注解、古文注解或者注釋,

在這里插入圖片描述
我們第一次接觸注解,可能是使用子類繼承父類的方法(任何物件的父類都是Object),看到重寫的注解@Override

package annotation;

/**
 * @ClassName Son
 * @Description 注解演示
 * @Author 古闕月
 * @Date 2021/4/8 19:00
 * @Version 1.0
 */
public class Son {

    @Override // 重寫的注解
    public String toString() {
        return super.toString();
    }
}

到后來Spring等框架中普遍使用了各種各樣的注解,注解的語法格式非常簡單:@ + 注解名,但是偏偏一個小小的注解,卻能在框架中實作各種各樣的功能,讓人不禁覺得灰常奇妙,而且簡單優雅!!!

注解的作用

注解(Annotation)主要有兩個作用:

  1. 注解(Annotation)就像注釋(Comment)一樣,它不屬于程式本身,但是可以對程式作出解釋,就比如我們一看到@Override注解,就知道該注解下的方法為重寫父類的方法,
  2. 我們可以通過其他程式,如編譯器讀取注解,然后再對注釋下的程式進行檢查和約束,或者我們可以利用反射技術來讀取注解,從而實作各種各樣的功能, 如重寫后的方法必須和父類的方法同名,我們試著改變方法名,就會出現報錯提醒:
    在這里插入圖片描述
    在這里插入圖片描述

內置注解

JDK內置了三個注解,下面來簡單介紹一下,

@Override

@Override注解的簡單使用在之前的章節已經介紹過了,它位于java.lang包下,官方解釋,看下面的檔案截圖:表示一個方法宣告打算重寫超類中的另一個方法宣告,如果方法利用此注釋型別進行注解但沒有重寫超類方法,則編譯器會生成一條錯誤訊息, 是不是跟我之前介紹的一樣?
在這里插入圖片描述
我們再點進去@Override來看一下它的源代碼:

package java.lang;

import java.lang.annotation.*;

/**
 * @author  Peter von der Ah&eacute;
 * @author  Joshua Bloch
 * @jls 9.6.1.4 @Override
 * @since 1.5
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

感覺似乎很懵,沒有關系,之后給你細細講解,

@Deprecated

@Deprecated注解 同樣位于java.lang包下,官方解釋為:@Deprecated 注釋的程式元素,不鼓勵程式員使用這樣的元素,通常是因為它很危隙訓存在更好的選擇,在使用不被贊成的程式元素或在不被贊成的代碼中執行重寫時,編譯器會發出警告,
在這里插入圖片描述
此注解用于修飾構造方法(CONSTRUCTOR)、屬性(FIELD)、區域變數(LOCAL_VARIABLE)、方法(METHOD)等,如我們用一個方法舉例子:

 	/**
     * 廢棄的方法
     */
    @Deprecated
    public static void deprecatedMethod() {
        System.out.println("我是一個被廢棄的方法...");
    }

當我們試圖使用deprecatedMethod()方法時,便會出現下劃線廢棄警告,表示不建議使用,危隙訓者有更好的選擇,
在這里插入圖片描述

當然,你要是想強行使用,也是可以的:

package annotation;

import lombok.ToString;

/**
 * @ClassName Son
 * @Description 注解演示
 * @Author 古闕月
 * @Date 2021/4/8 19:00
 * @Version 1.0
 */
public class Son {

    /**
     * 廢棄的方法
     */
    @Deprecated
    public static void deprecatedMethod() {
        System.out.println("我是一個被廢棄的方法...");
    }

    @Override // 重寫的注解
    public String toString() {

        return super.toString();
    }

    public static void main(String[] args) {
     	// 不建議使用的方法,不安全或者有更好的選擇
        deprecatedMethod();
    }
}

運行,得:
在這里插入圖片描述
同樣,這里貼出@Deprecated的源代碼:

package java.lang;

import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;

/**
 * @author  Neal Gafter
 * @since 1.5
 * @jls 9.6.3.6 @Deprecated
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}

如果看不懂,沒關系,之后講解,

@SuppressWarnings

@SuppressWarnings看字面意思很好理解:鎮壓警告 的意思,和之前的兩兄弟@Override以及@Deprecated一樣,位于java.lang包下,官方意思是:用于取消注釋元素中指定顯示的編譯器警告,詳情可見下圖檔案截圖:
在這里插入圖片描述
這樣看來似乎有些小抽象,沒關系,我們來舉一個例子:

	public void suppressWarningsMethod() {
	
		double num = 3.14;
	}

上文是一個方法,如果suppressWarningsMethod()方法以及num數值沒有被使用過的話,是會被暗化顯示的:
在這里插入圖片描述
我們完全可以用@SuppressWarnings注解來取消這個編譯器警告:

	@SuppressWarnings("unused") // 取消未使用便做暗化處理的編譯器警告
    public void suppressWarningsMethod() {

        double num = 3.14;
    }

效果如下:
在這里插入圖片描述
這個時候有細心的小伙伴可能就會發現了:之前使用重寫注解@Override以及廢棄注解@Deprecated時是直接使用的,可使用這個抑制警告注解@SuppressWarnings時,怎么是這么用的:@SuppressWarnings("unused") ,這個括號里面雙引號里面的 unused 是啥意思?

不要急,我們先來看一下@SuppressWarnings注解的原始碼

package java.lang;

import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;

/**
 * @author Josh Bloch
 * @since 1.5
 * @jls 4.8 Raw Types
 * @jls 4.12.2 Variables of Reference Type
 * @jls 5.1.9 Unchecked Conversion
 * @jls 5.5.2 Checked Casts and Unchecked Casts
 * @jls 9.6.3.5 @SuppressWarnings
 */
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
  
    String[] value();
}

這個時候,我們就會發現@SuppressWarnings注解跟之前兩個注解一個很大的不同,多了一個:

	String[] value();

這個value()像方法又沒有方法體,型別還是個String陣列,好像讓人有些看不懂!

這里提前透露一下,這個value()就是這個@SuppressWarnings的配置引數,value為這個配置引數的引數名,而value()是注解中配置引數的宣告形式,而String[] 則是這個名為value的配置引數的型別!!!

所以,當我們使用@SuppressWarnings注解時,后面需要加上引數,由勺ò干知,這個引數還可以為多個:

	@SuppressWarnings({"unused", "null"}) // 取消編譯器警告
    public void suppressWarningsMethod() {

        double num = 3.14;
    }

那么,這個引數值是不是隨便加的呢?那倒也不是,不同的引數有不同的含義,負責鎮壓不同的警告,具體含義如下表所示:

引數值含義
allto suppress all warnings(抑制所有警告)
boxing to suppress warnings relative to boxing/unboxing operations(要抑制與箱/非裝箱操作相關的警告)
castto suppress warnings relative to cast operations(為了抑制與強制轉換操作相關的警告))
dep-annto suppress warnings relative to deprecated annotation(要抑制相對于棄用注釋的警告)
deprecationto suppress warnings relative to deprecation(要抑制相對于棄用的警告)
fallthroughto suppress warnings relative to missing breaks in switch statements(在switch陳述句中,抑制與缺失中斷相關的警告)
finally to suppress warnings relative to finally block that don’t return(為了抑制警告,相對于最終阻止不回傳的警告)
hidingto suppress warnings relative to locals that hide variable(為了抑制本地隱藏變數的警告)
incomplete-switchto suppress warnings relative to missing entries in a switch statement (enum case)(為了在switch陳述句(enum案例)中抑制相對于缺失條目的警告)
nlsto suppress warnings relative to non-nls string literals(要抑制相對于非nls字串字面量的警告)
nullto suppress warnings relative to null analysis(為了抑制與null分析相關的警告)
rawtypesto suppress warnings relative to un-specific types when using generics on class params(在類params上使用泛型時,要抑制相對于非特異性型別的警告)
restrictionto suppress warnings relative to usage of discouraged or forbidden references(禁止使用警告或禁止參考的警告)
rawtypesto suppress warnings relative to un-specific types when using generics on class params(在類params上使用泛型時,要抑制相對于非特異性型別的警告)
serialto suppress warnings relative to missing serialVersionUID field for a serializable class(為了一個可串行化的類,為了抑制相對于缺失的serialVersionUID欄位的警告)
static-accesso suppress warnings relative to incorrect static access(o抑制與不正確的靜態訪問相關的警告)
synthetic-access to suppress warnings relative to unoptimized access from inner classes(相對于內部類的未優化訪問,來抑制警告)
uncheckedto suppress warnings relative to unchecked operations(相對于不受約束的操作,抑制警告)
unqualified-field-accessto suppress warnings relative to field access unqualified(為了抑制與現場訪問相關的警告)
unusedoto suppress warnings relative to unused code(抑制沒有使用過代碼的警告)

當大家看到最后一個unused時,是不是瞬間就知道了為什么本博主之前用的是@SuppressWarnings("unused")了呢?當然了,抑制警告注解@SuppressWarnings雖然是強迫癥的福利,但是平時作業中使用較少,大家了解下就好,也不必深究,

元注解

在之前我們已經了解了JDK內置的三個注解重寫注解@Override廢棄注解@Deprecated以及抑制警告注解@SuppressWarnings,想必大家已經比較清楚它們的作用了,那么注解的作用僅限于此嗎?

當然不是,看看框架里面那些注解,比如@RestController@Autowired等,就知道注解沒那么簡單了!!!

當然了,我們也可以自定義屬于自己的注解,這么一說,是不是有意思多了呢?

至于怎么自定義屬于自己的注解呢?這就不得不說到元注解了,

那么,什么是元注解呢?我們先來看之前重寫注解@Override的原始碼:

package java.lang;

import java.lang.annotation.*;

/**
 * @author  Peter von der Ah&eacute;
 * @author  Joshua Bloch
 * @jls 9.6.1.4 @Override
 * @since 1.5
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

我們會發現在重寫注解@Override的上方有這樣兩行代碼:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)

這個@Target以及@Retention就是所謂的元注解了!

元注解就是注解的注解,用于給其他注解作出說明!

在jdk1.5中總共定義了四個元注解供我們使用,他們分別是:

  1. @Target:用于描述注解的使用范圍,
  2. @Retention:用于描述注解的生命周期,指示注解要保留多久,
  3. @Documented:說明該注解被包含在javadoc中,
  4. @Inherited:表示子類可以繼承父類的該注解,

然后,在jdk1.8中又新定義le兩個元注解:

  1. @Native: 表示被注解的內容是原生(本機)相關的,(說白了就是去呼叫非Java語言實作的代碼,比如C)
  2. @Repeatable:表示該注解可以重復使用,

大家看到這里,想必也有些懵了:6個元注解,該怎么用呀?

不必擔心,簡化思維,我們重點關注前面兩個元注解就好了:@Target以及@Retention,而且這兩個元注解里面的值也是規定好了的列舉值,為什么說這兩個注解很重要呢?因為其他注解都可以少,唯獨這兩個注解必不可少!!!

@Target

含義之前已經講過了:用于描述注解的使用范圍,

我們來看一下@Target的源代碼:

package java.lang.annotation;

/**
 * @since 1.5
 * @jls 9.6.4.1 @Target
 * @jls 9.7.4 Where Annotations May Appear
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
   
    ElementType[] value();
}

這樣我們就會發現注解@Target里面的引數值是個ElementType陣列:

ElementType[] value();

點開ElementType的源代碼一看,這是個列舉型別

package java.lang.annotation;

/**
 *
 * @author  Joshua Bloch
 * @since 1.5
 * @jls 9.6.4.1 @Target
 * @jls 4.1 The Kinds of Types and Values
 */
public enum ElementType {
    /** Class, interface (including annotation type), or enum declaration */
    TYPE, // 類

    /** Field declaration (includes enum constants) */
    FIELD, // 屬性

    /** Method declaration */
    METHOD, // 方法

    /** Formal parameter declaration */
    PARAMETER, // 正式引數

    /** Constructor declaration */
    CONSTRUCTOR, // 建構式

    /** Local variable declaration */
    LOCAL_VARIABLE, // 區域變數

    /** Annotation type declaration */
    ANNOTATION_TYPE, // 注解型別

    /** Package declaration */
    PACKAGE, // 包

    /**
     * Type parameter declaration
     *
     * @since 1.8
     */
    TYPE_PARAMETER, // 鍵入引數

    /**
     * Use of a type
     *
     * @since 1.8
     */
    TYPE_USE // 使用型別
}

ElementType內各個值的含義已經寫在注釋上了,比如如果我們想某個注解能夠使用的類(TYPE)、方法(METHOD)以及屬性(FIELD)上,則應該在該注解上加上:

@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})

當然了,如果不使用@Target注解,該注解可以作用于任何元素上!!!

@Retention

同樣,該注解的含義之前也已經講過了:用于描述注解的生命周期,指示注解要保留多久,

我們也來看一下它的原始碼:

package java.lang.annotation;

/**
 * Indicates how long annotations with the annotated type are to
 * be retained.  If no Retention annotation is present on
 * an annotation type declaration, the retention policy defaults to
 * {@code RetentionPolicy.CLASS}.
 *
 * <p>A Retention meta-annotation has effect only if the
 * meta-annotated type is used directly for annotation.  It has no
 * effect if the meta-annotated type is used as a member type in
 * another annotation type.
 *
 * @author  Joshua Bloch
 * @since 1.5
 * @jls 9.6.3.2 @Retention
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {

    /**
     * Returns the retention policy.
     * @return the retention policy
     */
    RetentionPolicy value();
}

發現它的引數值也是一個列舉值RetentionPolicy

package java.lang.annotation;

/**
 * Annotation retention policy.  The constants of this enumerated type
 * describe the various policies for retaining annotations.  They are used
 * in conjunction with the {@link Retention} meta-annotation type to specify
 * how long annotations are to be retained.
 *
 * @author  Joshua Bloch
 * @since 1.5
 */
public enum RetentionPolicy {
    /**
     * Annotations are to be discarded by the compiler.
     * 原始碼
     */
    SOURCE,

    /**
     * Annotations are to be recorded in the class file by the compiler
     * but need not be retained by the VM at run time.  This is the default
     * behavior.
     * 編譯
     */
    CLASS,

    /**
     * Annotations are to be recorded in the class file by the compiler and
     * retained by the VM at run time, so they may be read reflectively.
     *
     * 運行時
     * @see java.lang.reflect.AnnotatedElement
     */
    RUNTIME
}

里面有三個值,它們的含義以及范圍大小關系為:

SOURCE(原始碼) < CLASS(編譯) < RUNTIME(運行時)

當然了,我們實際使用程序中 一般用runtime而如果當我們不使用@Retention注解時,默認為CLASS,也就是注解保留到編譯階段,

小小的總結一下:@Target以及@Retention注解是我們最常用到的注解,但是你不加上也沒關系,因為有默認值,但是我們一般會加上以便加以某種限制,

自定義注解

好了,在上一個章節,我們介紹了元注解,這里我們可以來學著自定義注解了,首先來介紹一下自定義注解的格式:

元注解
修飾符 @interface 注解名 {
	
	配置引數型別 配置引數名(); // 配置引數可以有多個,也可以沒有
}

比如@SuppressWarnings注解:

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
  
    String[] value();
}

當我們宣告了一個自定義注解,則自動繼承了java.lang.annotation.Annotation介面,如我們按照之前的語法規則自定義一個名為myAnnotation的注解:

// 該注解保留在運行時
@Retention(RetentionPolicy.RUNTIME)

// 該注解可作用在類、屬性、方法上
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
@interface myAnnotation {

    String[] value();
}

不過需要注意的是:配置引數的型別只能是基本資料型別、String、enum、注解型別,而不能是其他,比如Object、Integer等,

我們來簡單使用一下這個注解吧:

package annotation;

import java.lang.annotation.*;

/**
 * @ClassName MyAnnotationTest
 * @Description 自定義注解測驗類
 * @Author 古闕月
 * @Date 2021/4/11 16:23
 * @Version 1.0
 */
@myAnnotation("MyAnnotationTest")
public class MyAnnotationTest {

    @myAnnotation("main")
    public static void main(String[] args) {

    }
}

// 該注解保留在運行時
@Retention(RetentionPolicy.RUNTIME)

// 該注解可作用在類、屬性、方法上
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
@interface myAnnotation {

    String[] value();
}

此處,還有一點細節,如果自定義注解內配置引數僅有一個時并且配置引數名為value,配置引數名可省略:

@myAnnotation("MyAnnotationTest")
public class MyAnnotationTest {

    @myAnnotation("main")
    public static void main(String[] args) {

    }
}

但是如果有多個,或者配置引數名為一個且不為value,則需要加上引數名,如:

// 該注解保留在運行時
@Retention(RetentionPolicy.RUNTIME)

// 該注解可作用在類、屬性、方法上
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
@interface myAnnotation {

    String[] value();

    // 修飾符
    String modifier();
}

應當加上引數名:

@myAnnotation(value = "MyAnnotationTest", modifier = "public")
public class MyAnnotationTest {

    @myAnnotation(value = "main", modifier = "public")
    public static void main(String[] args) {

    }
}

但是,在配置引數后面可以加上默認值,語法為:

配置引數型別 配置引數名() default 默認值;

如果有默認值的話,我們在使用注解時,可以不手動加入配置引數值,如:

// 該注解保留在運行時
@Retention(RetentionPolicy.RUNTIME)

// 該注解可作用在類、屬性、方法上
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
@interface myAnnotation {

    String[] value() default "methodName";

    // 修飾符
    String modifier() default "public";
}

可以不加配置引數值,后面的括號也可有可無:

@myAnnotation()
public class MyAnnotationTest {

    @myAnnotation
    public static void main(String[] args) {

    }
}

總之,得保證一定有值就對了!!!

尾聲

好了,到這里這篇介紹注解的博客就結束了,如果有一定基礎的小伙伴,估計會說:就這?那框架里面怎么使用的注解呀?你這啥功能都沒實作,都沒有呀!那要這注解有何用?
在這里插入圖片描述
其實我真的挺冤枉的:博客陸陸續續寫了一個多禮拜,也肝了近一萬五千字了,只來得及寫一些簡單的介紹以及基本語法,實在是肝不動了,至于注解如何結合Spring框架的IOC以及AOP思想,實作種種神奇的功能?比如我們常見的事務,

欲知后事如何,請聽下回分解!!!

能看到這里,并且看完我的碎碎念的 估計是神人了,我猜是沒有多少人看到這里的,創作不易,如果覺得不錯的話,順手給個點贊、評論以及收藏加關注唄!如果有哪里講的不對的地方,也非常歡迎評論指正哦!

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/275452.html

標籤:java

上一篇:Java-----多執行緒【執行緒通信問題 與 兩大解決方式】

下一篇:day2 javaee的入門知識

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more