亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

Table des matières
1. En commen?ant par l'allocation de mémoire des cha?nes String
1.一個關(guān)于intern()的簡單例子
2.改造例子,再看intern
2).JDK6的運(yùn)行結(jié)果分析
三、String類的結(jié)構(gòu)及特性分析
1.不同JDK版本之間String的差異
2.String字符串的裁剪、拼接等操作分析
(1)String的substring實(shí)現(xiàn)
(2)String的字符串拼接實(shí)現(xiàn)
1)字符串拼接方案性能對比
2)三種字符串拼接方案原理分析
四、總結(jié)
Maison Java JavaBase Passez en revue le passé et apprenez le nouveau (1) Compréhension approfondie des cha?nes en Java

Passez en revue le passé et apprenez le nouveau (1) Compréhension approfondie des cha?nes en Java

Sep 18, 2020 pm 05:32 PM
java Cha?ne

Passez en revue le passé et apprenez le nouveau (1) Compréhension approfondie des cha?nes en Java

Recommandations d'apprentissage associées?: Tutoriel de base Java

Débutant En Java, nous savons déjà que Java peut être divisé en deux principaux types de données, à savoir les types de données de base et les types de données de référence. Parmi ces deux types de données, il existe un type de données spécial, String, qui est un type de données de référence, mais il est différent des autres types de données de référence. On peut dire que c'est une fleur étrange parmi les types de données. Ainsi, dans cet article, nous aurons une compréhension approfondie des cha?nes String en Java.

1. En commen?ant par l'allocation de mémoire des cha?nes String

L'article précédent "Revoir le passé et apprendre de nouvelles choses - L'allocation de mémoire JVM que vous ne connaissez pas" a analysé le modèle de mémoire JVM en détail . Dans la section sur les pools de constantes, nous avons découvert trois types de pools de constantes, à savoir?: le pool de constantes de cha?ne, le pool de constantes de fichier de classe et le pool de constantes d'exécution. L'allocation de mémoire des cha?nes a une excellente relation avec le pool de constantes de cha?ne.

Nous savons que l'instanciation d'une cha?ne peut être réalisée de deux manières. La première méthode, la plus couramment utilisée, consiste à effectuer une affectation littérale, et l'autre consiste à transmettre des paramètres via le constructeur. Le code est le suivant?:

    String str1="abc";
    String str2=new String("abc");復(fù)制代碼

Quelle est la différence entre ces deux méthodes d'allocation de mémoire?? Je crois que le professeur nous l'a expliqué lorsque nous avons appris Java pour la première fois?:

1. Passer la création d’une cha?ne via une affectation littérale ne générera qu’un objet String dans le pool de constantes de cha?ne. 2. Passer le paramètre String via le constructeur générera un objet String dans la mémoire du tas et le pool de constantes de cha?ne, et placera la référence à la cha?ne dans la mémoire du tas dans la pile.

Cette réponse est-elle correcte?? Cela ne semble pas tout à fait correct, du moins pour le moment, car cela dépend entièrement de la version Java utilisée. L'article précédent ? Passer en revue le passé et apprendre le nouveau - L'allocation de mémoire JVM que vous ne connaissez pas ? parlait de l'implémentation par la machine virtuelle HotSpot du pool de constantes de cha?ne sur différents JDK. L'extrait est le suivant?:

<. ??> dans Avant JDK7, le pool de constantes de cha?ne se trouvait dans la zone de méthode (génération permanente). à cette époque, le pool de constantes stockait les objets de cha?ne. Dans JDK7, le pool de constantes de cha?ne est déplacé de la zone de méthode vers la mémoire du tas et l'objet cha?ne est stocké dans le tas Java. Le pool de constantes de cha?ne stocke uniquement les références aux objets cha?ne.

Comment faut-il comprendre cette phrase ? Prenons String str1=new String("abc") comme exemple pour analyser?:

1. Allocation de mémoire dans le JDK6

Analysons d'abord l'allocation de mémoire du JDK6, comme le montre la figure. ci-dessous?:

Passez en revue le passé et apprenez le nouveau (1) Compréhension approfondie des cha?nes en Java
Lorsque new String("abc") est appelé, un objet "abc" sera généré dans le tas Java et le pool de constantes . En même temps, pointez str1 vers l'objet "abc" dans le tas.

2. Allocation de mémoire dans JDK7

Dans JDK7 et les versions ultérieures, étant donné que le pool de constantes de cha?ne est déplacé vers la mémoire tas, la méthode d'allocation de mémoire est également différente, comme le montre la figure ci-dessous. :

Passez en revue le passé et apprenez le nouveau (1) Compréhension approfondie des cha?nes en Java
Lorsque new String("abc") est appelé, deux objets "abc" seront créés dans la mémoire du tas, et str1 pointe vers eux. Un objet "abc" et une référence à l'objet "abc" seront générés dans le pool de constantes et pointeront vers un autre objet "abc".

Quant à la raison pour laquelle Java est con?u de cette fa?on, nous l'avons déjà expliqué dans l'article précédent?:

Parce que String est le type de données le plus fréquemment utilisé en Java, afin d'économiser la mémoire du programme et d'améliorer les performances du programme. , Les concepteurs de Java ont ouvert une zone de pool de constantes de cha?ne, qui est partagée par toutes les classes. Chaque machine virtuelle n'a qu'un seul pool de constantes de cha?ne. Par conséquent, lors de l'utilisation d'une affectation littérale, si la cha?ne existe déjà dans le pool de constantes de cha?ne, l'objet ne sera pas recréé dans la mémoire tas, mais sera pointé directement vers l'objet dans le pool de constantes de cha?ne.

2. Méthode intern() de String

Après avoir compris l'allocation de mémoire de String, nous devons conna?tre une méthode très importante dans String : String.intern() .

De nombreux lecteurs ne savent peut-être pas grand chose sur cette méthode, mais cela ne veut pas dire qu'elle n'est pas importante. Jetons d'abord un coup d'?il au code source de la méthode intern() :

/**
     * Returns a canonical representation for the string object.
     * <p>
     * A pool of strings, initially empty, is maintained privately by the
     * class {@code String}.
     * <p>
     * When the intern method is invoked, if the pool already contains a
     * string equal to this {@code String} object as determined by
     * the {@link #equals(Object)} method, then the string from the pool is
     * returned. Otherwise, this {@code String} object is added to the
     * pool and a reference to this {@code String} object is returned.
     * <p>
     * It follows that for any two strings {@code s} and {@code t},
     * {@code s.intern() == t.intern()} is {@code true}
     * if and only if {@code s.equals(t)} is {@code true}.
     * <p>
     * All literal strings and string-valued constant expressions are
     * interned. String literals are defined in section 3.10.5 of the
     * <cite>The Java&trade; Language Specification</cite>.
     *
     * @return  a string that has the same contents as this string, but is
     *          guaranteed to be from a pool of unique strings.
     */
    public native String intern();復(fù)制代碼

emmmmm.... C'est en fait une méthode native, mais cela n'a pas d'importance même si on ne voit pas la source. code, nous pouvons obtenir quelques informations à partir de ses commentaires :

Lors de l'appel de la méthode interne, si le pool de constantes de cha?ne contient déjà une cha?ne égale à l'objet String, la référence à la cha?ne dans le pool de constantes de cha?ne sera directement renvoyée. Sinon, la cha?ne contenue par cet objet cha?ne est ajoutée au pool de constantes et une référence à cet objet est renvoyée.

1.一個關(guān)于intern()的簡單例子

了解了intern方法的用途之后,來看一個簡單的列子:

public class Test {    public static void main(String[] args) {
        String str1 = "hello world";
        String str2 = new String("hello world");
        String str3=str2.intern();
        System.out.println("str1 == str2:"+(str1 == str2));
        System.out.println("str1 == str3:"+(str1 == str3));
    }
}復(fù)制代碼

上面的一段代碼會輸出什么?編譯運(yùn)行之后如下:

Passez en revue le passé et apprenez le nouveau (1) Compréhension approfondie des cha?nes en Java

如果理解了intern方法就很容易解釋這個結(jié)果了,從上面截圖中可以看到,我們的運(yùn)行環(huán)境是JDK8。

String str1 = "hello world"; 這行代碼會首先在Java堆中創(chuàng)建一個對象,并將該對象的引用放入字符串常量池中,str1指向常量池中的引用。

String str2 = new String("hello world");這行代碼會通過new來實(shí)例化一個String對象,并將該對象的引用賦值給str2,然后檢測字符串常量池中是否已經(jīng)有了與“hello world”相等的對象,如果沒有,則會在堆內(nèi)存中再生成一個值為"hello world"的對象,并將其引用放入到字符串常量池中,否則,不會再去創(chuàng)建。這里,第一行代碼其實(shí)已經(jīng)在字符串常量池中保存了“hello world”字符串對象的引用,因此,第二行代碼就不會再次向常量池中添加“hello world"的引用。

String str3=str2.intern(); 這行代碼會首先去檢測字符串常量池中是否已經(jīng)包含了”hello world"的String對象,如果有則直接返回其引用。而在這里,str2.intern()其實(shí)剛好返回了第一行代碼中生成的“hello world"對象。

因此【System.out.println("str1 == str3:"+(str1 == str3));】這行代碼會輸出true.

如果切到JDK6,其打印結(jié)果與上一致,至于原因讀者可以自行分析。

Passez en revue le passé et apprenez le nouveau (1) Compréhension approfondie des cha?nes en Java

2.改造例子,再看intern

上一節(jié)中我們通過一個例子認(rèn)識了intern()方法的作用,接下來,我們對上述例子做一些修改:

public class Test {
    public static void main(String[] args) {
        String str1=new String("he")+new String("llo");
        String str2=str1.intern();
        String str3="hello";
        System.out.println("str1 == str2:"+(str1 == str2));
        System.out.println("str2 == str3:"+(str2 == str3)); 
    }
}復(fù)制代碼

先別急著看下方答案,思考一下在JDK7(或JDK7之后)及JDK6上會輸出什么結(jié)果?

1).JDK8的運(yùn)行結(jié)果分析

我們先來看下我們先來看下JDK8的運(yùn)行結(jié)果:

Passez en revue le passé et apprenez le nouveau (1) Compréhension approfondie des cha?nes en Java

通過運(yùn)行程序發(fā)現(xiàn)輸出的兩個結(jié)果都是true,這是為什么呢?我們通過一個圖來分析:

Passez en revue le passé et apprenez le nouveau (1) Compréhension approfondie des cha?nes en Java

String str1=new String("he")+new String("llo"); 這行代碼中new String("he")和new String("llo")會在堆上生成四個對象,因?yàn)榕c本例無關(guān),所以圖上沒有畫出,new String("he")+new String("llo")通過”+“號拼接后最終會生成一個"hello"對象并賦值給str1。

String str2=str1.intern(); 這行代碼會首先檢測字符串常量池,發(fā)現(xiàn)此時還沒有存在與”hello"相等的字符串對象的引用,而在檢測堆內(nèi)存時發(fā)現(xiàn)堆中已經(jīng)有了“hello"對象,遂將堆中的”hello"對象的應(yīng)用放入字符串常量池中。

String str3="hello"; 這行代碼發(fā)現(xiàn)字符串常量池中已經(jīng)存在了“hello"對象的引用,因此將str3指向了字符串常量池中的引用。

此時,我們發(fā)現(xiàn)str1、str2、str3指向了堆中的同一個”hello"對象,因此,就有了上邊兩個均為true的輸出結(jié)果。

2).JDK6的運(yùn)行結(jié)果分析

我們將運(yùn)行環(huán)境切換到JDK6,來看下其輸出結(jié)果:

Passez en revue le passé et apprenez le nouveau (1) Compréhension approfondie des cha?nes en Java

有點(diǎn)意思!相同的代碼在不同的JDK版本上輸出結(jié)果竟然不相等。這是怎么回事呢?我們還通過一張圖來分析:

Passez en revue le passé et apprenez le nouveau (1) Compréhension approfondie des cha?nes en Java

String str1=new String("he")+new String("llo"); 這行代碼會通過new String("he")和new String("llo")會分別在Java堆與字符串常量池中各生成兩個String對象,由于與本例無關(guān),所以并沒有在圖中畫出。而new String("he")+new String("llo")通過“+”號拼接后最終會在Java堆上生成一個"hello"對象,并將其賦值給了str1。

String str2=str1.intern(); 這行代碼檢測到字符串常量池中還沒有“hello"對象,因此將堆中的”hello“對象復(fù)制到了字符串常量池,并將其賦值給str2。

String str3="hello"; 這行代碼檢測到字符串常量池中已經(jīng)有了”hello“對象,因此直接將str3指向了字符串常量池中的”hello“對象。 此時str1指向的是Java堆中的”hello“對象,而str2和str3均指向了字符串常量池中的對象。因此,有了上面的輸出結(jié)果。

通過這兩個例子,相信大家因該對String的intern()方法有了較深的認(rèn)識。那么intern()方法具體在開發(fā)中有什么用呢?推薦大家可以看下美團(tuán)技術(shù)團(tuán)隊(duì)的一篇文章《深入解析String#intern》中舉的兩個例子。限于篇幅,本文不再舉例分析。

三、String類的結(jié)構(gòu)及特性分析

前兩節(jié)我們認(rèn)識了String的內(nèi)存分配以及它的intern()方法,這兩節(jié)內(nèi)容其實(shí)都是對String內(nèi)存的分析。到目前為止,我們還并未認(rèn)識String類的結(jié)構(gòu)以及它的一些特性。那么本節(jié)內(nèi)容我們就此來分析。先通過一段代碼來大致了解一下String類的結(jié)構(gòu)(代碼取自jdk8):

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {        /** The value is used for character storage. */
        private final char value[];        /** Cache the hash code for the string */
         private int hash; // Default to 0
        //  ...}復(fù)制代碼

可以看到String類實(shí)現(xiàn)了Serializable接口、Comparable接口以及CharSequence接口,意味著它可以被序列化,同時方便我們排序。另外,String類還被聲明為了final類型,這意味著String類是不能被繼承的。而在其內(nèi)部維護(hù)了一個char數(shù)組,說明String是通過char數(shù)組來實(shí)現(xiàn)的,同時我們注意到這個char數(shù)組也被聲明為了final,這也是我們常說的String是不可變的原因。

1.不同JDK版本之間String的差異

Java的設(shè)計(jì)團(tuán)隊(duì)一直在對String類進(jìn)行優(yōu)化,這就導(dǎo)致了不同jdk版本上String類的實(shí)現(xiàn)有些許差異,只是我們使用上并無感知。下圖列出了jdk6-jdk9中String源碼的一些變化。

Passez en revue le passé et apprenez le nouveau (1) Compréhension approfondie des cha?nes en Java

可以看到在Java6之前String中維護(hù)了一個char 數(shù)組、一個偏移量 offset、一個字符數(shù)量 count以及一個哈希值 hash。 String對象是通過 offset 和 count 兩個屬性來定位 char[] 數(shù)組,獲取字符串。這么做可以高效、快速地共享數(shù)組對象,同時節(jié)省內(nèi)存空間,但這種方式很有可能會導(dǎo)致內(nèi)存泄漏。

在Java7和Java8的版本中移除了 offset 和 count 兩個變量了。這樣的好處是String對象占用的內(nèi)存稍微少了些,同時 String.substring 方法也不再共享 char[],從而解決了使用該方法可能導(dǎo)致的內(nèi)存泄漏問題。

從Java9開始,String中的char數(shù)組被byte[]數(shù)組所替代。我們知道一個char類型占用兩個字節(jié),而byte占用一個字節(jié)。因此在存儲單字節(jié)的String時,使用char數(shù)組會比byte數(shù)組少一個字節(jié),但本質(zhì)上并無任何差別。 另外,注意到在Java9的版本中多了一個coder,它是編碼格式的標(biāo)識,在計(jì)算字符串長度或者調(diào)用 indexOf() 函數(shù)時,需要根據(jù)這個字段,判斷如何計(jì)算字符串長度。coder 屬性默認(rèn)有 0 和 1 兩個值, 0 代表Latin-1(單字節(jié)編碼),1 代表 UTF-16 編碼。如果 String判斷字符串只包含了 Latin-1,則 coder 屬性值為 0 ,反之則為 1。

2.String字符串的裁剪、拼接等操作分析

在本節(jié)內(nèi)容的開頭我們已經(jīng)知道了字符串的不可變性。那么為什么我們還可以使用String的substring方法進(jìn)行裁剪,甚至可以直接使用”+“連接符進(jìn)行字符串的拼接呢?

(1)String的substring實(shí)現(xiàn)

關(guān)于substring的實(shí)現(xiàn),其實(shí)我們直接深入String的源碼查看即可,源碼如下:

    public String substring(int beginIndex) {            if (beginIndex < 0) {                throw new StringIndexOutOfBoundsException(beginIndex);
            }            int subLen = value.length - beginIndex;            if (subLen < 0) {                throw new StringIndexOutOfBoundsException(subLen);
            }            return (beginIndex == 0) ? this : new String(value, beginIndex, subLen);
        }復(fù)制代碼

從這段代碼中可以看出,其實(shí)字符串的裁剪是通過實(shí)例化了一個新的String對象來實(shí)現(xiàn)的。所以,如果在項(xiàng)目中存在大量的字符串裁剪的代碼應(yīng)盡量避免使用String,而是使用性能更好的StringBuilder或StringBuffer來處理。

(2)String的字符串拼接實(shí)現(xiàn)

1)字符串拼接方案性能對比

關(guān)于字符串的拼接有很多實(shí)現(xiàn)方法,在這里我們舉三個例子來進(jìn)行一個性能對比,分別如下:

使用”+“操作符拼接字符串

    public class Test {        private static final int COUNT=50000;        public static void main(String[] args) {
            String str="";            for(int i=0;i<COUNT;i++) {
                str=str+"abc";
            }
    }復(fù)制代碼

使用String的concat()方法拼接

    public class Test {        private static final int COUNT=50000;        public static void main(String[] args) {
            String str="";            for(int i=0;i<COUNT;i++) {
                str=str+"abc";
            }
    }復(fù)制代碼

使用StringBuilder的append方法拼接

    public class Test {        private static final int COUNT=50000;        public static void main(String[] args) {
            StringBuilder str=new StringBuilder();            for(int i=0;i<COUNT;i++) {
                str.append("abc");
            }
    }復(fù)制代碼

如上代碼,通過三種方法分別進(jìn)行了50000次字符串拼接,每種方法分別運(yùn)行了20次。統(tǒng)計(jì)耗時,得到以下表格:

拼接方法最小用時(ms)最大用時(ms)平均用時(ms)
"+"操作符486851464924
String的concat方法222724562296
StringBuilder的append方法4126.6

從以上數(shù)據(jù)中可以很直觀的看到”+“操作符的性能是最差的,平均用時達(dá)到了4924ms。其次是String的concat方法,平均用時也在2296ms。而表現(xiàn)最為優(yōu)秀的是StringBuilder的append方法,它的平均用時竟然只有6.6ms。這也是為什么在開發(fā)中不建議使用”+“操作符進(jìn)行字符串拼接的原因。

2)三種字符串拼接方案原理分析

”+“操作符的實(shí)現(xiàn)原理由于”+“操作符是由JVM來完成的,我么無法直接看到代碼實(shí)現(xiàn)。不過Java為我們提供了一個javap的工具,可以幫助我們將Class文件進(jìn)行一個反匯編,通過匯編指令,大致可以看出”+“操作符的實(shí)現(xiàn)原理。

    public class Test {        private static final int COUNT=50000;        public static void main(String[] args) {            for(int i=0;i<COUNT;i++) {
                str=str+"abc";
            }
    }復(fù)制代碼

把上邊這段代碼編譯后,執(zhí)行javap,得到如下結(jié)果:

Passez en revue le passé et apprenez le nouveau (1) Compréhension approfondie des cha?nes en Java

注意圖中的”11:“行指令處實(shí)例化了一個StringBuilder,在"19:"行處調(diào)用了StringBuilder的append方法,并在第”27:"行處調(diào)用了String的toString()方法??梢姡琂VM在進(jìn)行”+“字符串拼接時也是用了StringBuilder來實(shí)現(xiàn)的,但為什么與直接使用StringBuilder的差距那么大呢?其實(shí),只要我們將上邊代碼轉(zhuǎn)換成虛擬機(jī)優(yōu)化后的代碼一看便知:

    public class Test {        private static final int COUNT=50000;        public static void main(String[] args) {
            String str="";            for(int i=0;i<COUNT;i++) {
                str=new StringBuilder(str).append("abc").toString();
            }
    }復(fù)制代碼

可見,優(yōu)化后的代碼雖然也是用的StringBuilder,但是StringBuilder卻是在循環(huán)中實(shí)例化的,這就意味著循環(huán)了50000次,創(chuàng)建了50000個StringBuilder對象,并且調(diào)用了50000次toString()方法。怪不得用了這么長時間?。?!

String的concat方法的實(shí)現(xiàn)原理關(guān)于concat方法可以直接到String內(nèi)部查看其源碼,如下:

public String concat(String str) {        int otherLen = str.length();        if (otherLen == 0) {            return this;
        }        int len = value.length;        char buf[] = Arrays.copyOf(value, len + otherLen);
        str.getChars(buf, len);        return new String(buf, true);
    }復(fù)制代碼

可以看到,在concat方法中使用Arrays的copyOf進(jìn)行了一次數(shù)組拷貝,接下來又通過getChars方法再次進(jìn)行了數(shù)組拷貝,最后通過new實(shí)例化了String對象并返回。這也意味著每調(diào)用一次concat都會生成一個String對象,但相比”+“操作符卻省去了toString方法。因此,其性能要比”+“操作符好上不少。

至于StringBuilder其實(shí)也沒必要再去分析了,畢竟”+“操作符也是基于StringBuilder實(shí)現(xiàn)的,只不過拼接過程中”+“操作符創(chuàng)建了大量的對象。而StringBuilder拼接時僅僅創(chuàng)建了一個StringBuilder對象。

四、總結(jié)

本篇文章我們深入分析了String字符串的內(nèi)存分配、intern()方法,以及String類的結(jié)構(gòu)及特性。關(guān)于這塊知識,網(wǎng)上的文章魚龍混雜,甚至眾說紛紜。筆者也是參考了大量的文章并結(jié)合自己的理解來做的分析。但是,避免不了的可能會出現(xiàn)理解偏差的問題,如果有,希望大家多多討論給予指正。 同時,文章中多次提到StringBuilder,但限于文章篇幅,沒能給出關(guān)于其詳細(xì)分析。不過不用擔(dān)心,我會在下一篇文章中再做探討。 不管怎樣,相信大家看完這篇文章后一定 對String有了更加深入的認(rèn)識,尤其是了解String類的一些裁剪及拼接中可能造成的性能問題,在今后的開發(fā)中應(yīng)該盡量避免。


Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefa?on, veuillez contacter admin@php.cn

Outils d'IA chauds

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

Video Face Swap

Video Face Swap

échangez les visages dans n'importe quelle vidéo sans effort grace à notre outil d'échange de visage AI entièrement gratuit?!

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Sujets chauds

Tutoriel PHP
1488
72
VSCODE Settings.json Emplacement VSCODE Settings.json Emplacement Aug 01, 2025 am 06:12 AM

Le fichier SetfitS.JSON est situé dans le chemin de niveau utilisateur ou au niveau de l'espace de travail et est utilisé pour personnaliser les paramètres VScode. 1. Chemin de niveau utilisateur: Windows est C: \ Users \\ AppData \ Roaming \ Code \ User \ Settings.json, macOS est /users//library/applicationsupport/code/user/settings.json, Linux est /home//.config/code/user/settings.json; 2. Chemin au niveau de l'espace de travail: .vscode / Paramètres dans le répertoire racine du projet

Comment gérer les transactions en Java avec JDBC? Comment gérer les transactions en Java avec JDBC? Aug 02, 2025 pm 12:29 PM

Pour gérer correctement les transactions JDBC, vous devez d'abord désactiver le mode de validation automatique, puis effectuer plusieurs opérations, et enfin vous engager ou randonner en fonction des résultats; 1. Appelez Conn.SetAutoCommit (false) pour démarrer la transaction; 2. Exécuter plusieurs opérations SQL, telles que l'insertion et la mise à jour; 3. Appelez Conn.Commit () Si toutes les opérations sont réussies, et appelez Conn.Rollback () Si une exception se produit pour garantir la cohérence des données; Dans le même temps, les ressources TRY-With doivent être utilisées pour gérer les ressources, gérer correctement les exceptions et cl?turer les connexions pour éviter la fuite de connexion; De plus, il est recommandé d'utiliser des pools de connexion et de définir des points de sauvegarde pour réaliser un retour en arrière partiel, et de maintenir les transactions aussi courtes que possible pour améliorer les performances.

Mastering Injection de dépendance en Java avec le printemps et Guice Mastering Injection de dépendance en Java avec le printemps et Guice Aug 01, 2025 am 05:53 AM

DépendanceInjection (DI) IsadesignPatternwhereBjectSeveveveltency dexternal, promotionnloosecouplingAndreasiestingthroughroughConstructor, seter, orfieldInjection.2.springframeworkusesannotations like @ composant, @ service et @ autowiredwithjava-baskusecondotations like @ composant, @ service et @ autowiredwithjava-basesConfitations lik

Exemple de combinaisons Python Itertools Exemple de combinaisons Python Itertools Jul 31, 2025 am 09:53 AM

itertools.combinations est utilisé pour générer toutes les combinaisons non répétitives (ordre hors de propos) qui sélectionne un nombre spécifié d'éléments de l'objet itérable. Son utilisation comprend: 1. Sélectionnez 2 combinaisons d'éléments dans la liste, telles que ('a', 'b'), ('a', 'c'), etc., pour éviter l'ordre répété; 2. Prenez 3 combinaisons de caractères de cha?nes, telles que "ABC" et "ABD", qui conviennent à la génération de sous-séquence; 3. Trouvez les combinaisons où la somme de deux nombres est égale à la valeur cible, telle que 1 5 = 6, simplifiez la logique de boucle double; La différence entre les combinaisons et l'arrangement réside dans la question de savoir si l'ordre est important, les combinaisons considèrent AB et BA comme les mêmes, tandis que les permutations sont considérées comme différentes;

Dépannage des scénarios Java ?OutofMemoryError? Dépannage des scénarios Java ?OutofMemoryError? Jul 31, 2025 am 09:07 AM

java.lang.outofMemoryError: javaheapspace indique une mémoire de tas insuffisante et doit vérifier le traitement des grands objets, des fuites de mémoire et des paramètres de tas, et localiser et optimiser le code via l'outil d'analyse de vidage du tas; 2. Les erreurs de métaspace sont courantes dans la génération de classe dynamique ou le déploiement à chaud en raison des métadonnées de classe excessive, et MaxMetAspaceSize doit être restreint et la charge de classe doit être optimisée; 3. UNCHETOCEATEENEWNATIVETHREALD En raison des ressources de threads du système épuisantes, il est nécessaire de vérifier le nombre de threads, d'utiliser des pools de threads et de régler la taille de la pile; 4. GcoverheadLimitexeded signifie que GC est fréquent mais a moins de recyclage, et les journaux GC doivent être analysés et optimisés.

Exemple de luminaire Python Pytest Exemple de luminaire Python Pytest Jul 31, 2025 am 09:35 AM

Le luminaire est une fonction utilisée pour fournir un environnement prédéfini ou des données pour les tests. 1. Utilisez le décorateur @ pytest.fixture pour définir le luminaire; 2. Injection de fixation sous forme de paramètre dans la fonction de test; 3. Exécutez la configuration avant le rendement, puis le démolition; 4. Contr?le Portée à travers les paramètres de portée, tels que la fonction, le module, etc.; 5. Placez le luminaire partagé dans Conftest.py pour atteindre le partage croisé, améliorant ainsi la maintenabilité et la réutilisabilité des tests.

Comment travailler avec le calendrier à Java? Comment travailler avec le calendrier à Java? Aug 02, 2025 am 02:38 AM

Utilisez des classes dans le package Java.Time pour remplacer les anciennes classes de date et de calendrier; 2. Obtenez la date et l'heure actuelles via LocalDate, LocalDateTime et Localtime; 3. Créez une date et une heure spécifiques en utilisant la méthode OF (); 4. Utilisez la méthode plus / moins pour augmenter et diminuer le temps; 5. Utilisez ZonedDateTime et ZoneID pour traiter le fuseau horaire; 6. Format et cha?nes de date d'analyse via DateTimeFormatter; 7. Utilisez instantanément pour être compatible avec les anciens types de dates si nécessaire; Le traitement des dattes dans le Java moderne devrait donner la priorité à l'utilisation de Java.timeapi, qui fournit clairement, immuable et linéaire

Comprendre les internes de la machine virtuelle Java (JVM) Comprendre les internes de la machine virtuelle Java (JVM) Aug 01, 2025 am 06:31 AM

Les capacités de ?écriture, runany?

See all articles