国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

目次
1. String 文字列のメモリ割り當(dāng)てから始めましょう
読者の多くはこの方法についてあまり知らないかもしれませんが、重要ではないというわけではありません。まず intern() メソッドのソース コードを見(jiàn)てみましょう:
1.一個(gè)關(guān)于intern()的簡(jiǎn)單例子
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)字符串拼接方案性能對(duì)比
2)三種字符串拼接方案原理分析
四、總結(jié)
ホームページ Java &#&ベース 過(guò)去を振り返り、新しいことを?qū)Wぶ (1) Javaの文字列を深く理解する

過(guò)去を振り返り、新しいことを?qū)Wぶ (1) Javaの文字列を深く理解する

Sep 18, 2020 pm 05:32 PM
java

過(guò)去を振り返り、新しいことを?qū)Wぶ (1) Javaの文字列を深く理解する

関連する學(xué)習(xí)に関する推奨事項(xiàng): Java 基本チュートリアル

初心者向けJava では、Java が 2 つの主要なデータ型、つまり基本データ型と參照データ型に分類できることはすでに知られています。これら 2 つのデータ型のうち、String という特殊なデータ型があり、String は參照データ型ですが、他の參照データ型とは異なります。データ型の中でも奇抜な花と言えるでしょう。したがって、この記事では、Java の String 文字列について詳しく理解します。

1. String 文字列のメモリ割り當(dāng)てから始めましょう

前回の記事「過(guò)去を振り返り、新しいことを?qū)Wぶ -- あなたの知らない JVM メモリ割り當(dāng)て」では、JVM メモリ モデルを分析しました。詳細(xì)に。定數(shù)プールのセクションでは、文字列定數(shù)プール、クラス ファイル定數(shù)プール、実行時(shí)定數(shù)プールの 3 種類の定數(shù)プールについて學(xué)びました。文字列のメモリ割り當(dāng)ては、文字列定數(shù)プールと大きな関係があります。

文字列のインスタンス化には 2 つの方法があることがわかっています。1 つ目の最も一般的に使用される方法は、リテラル代入によるもので、もう 1 つはパラメータを渡す構(gòu)築方法によるものです。コードは次のとおりです:

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

メモリ割り當(dāng)てにおけるこれら 2 つの方法の違いは何ですか? 私たちが初めて Java を?qū)W習(xí)したときに、先生が説明してくれたと思います:

1。リテラル割り當(dāng)てによる文字列の作成を渡すと、文字列定數(shù)プールに String オブジェクトのみが生成されます。 2. コンストラクターを介して String パラメーターを渡すと、ヒープ メモリと文字列定數(shù)プールに String オブジェクトが生成され、ヒープ メモリ內(nèi)の String への參照がスタックに置かれます。

#この答えは正しいですか?それは使用される Java バージョンに完全に依存するため、少なくとも現(xiàn)時(shí)點(diǎn)では完全に正しいとは言えないようです。前回の記事「過(guò)去を振り返り、新しいことを?qū)Wぶ - あなたの知らない JVM メモリ割り當(dāng)て」では、HotSpot 仮想マシンのさまざまな JDK での文字列定數(shù)プールの実裝について説明しました。 ## JDK7以前は文字列定數(shù)プールはメソッド領(lǐng)域(永続生成)にあり、このときは文字列オブジェクトが格納されていました。 JDK7では、文字列定數(shù)プールはメソッド領(lǐng)域からヒープメモリに移動(dòng)され、文字列オブジェクトはJavaヒープに格納されますが、文字列定數(shù)プールには文字列オブジェクトへの參照のみが格納されます。

この文をどのように理解すればよいでしょうか? String str1=new String("abc") を分析する例として取り上げます:

1. JDK6 のメモリ割り當(dāng)て

図に示すように、まず JDK6 のメモリ割り當(dāng)てを分析しましょう。以下:

過(guò)去を振り返り、新しいことを?qū)Wぶ (1) Javaの文字列を深く理解するnew String("abc") が呼び出されると、Java ヒープと定數(shù)プールに "abc" オブジェクトが生成されます。同時(shí)に、str1 がヒープ內(nèi)の「abc」オブジェクトを指すようにします。
2.JDK7 でのメモリ割り當(dāng)て

JDK7 以降のバージョンでは、文字列定數(shù)プールがヒープ メモリに移動(dòng)されるため、次の図に示すようにメモリ割り當(dāng)て方法も異なります。 :

過(guò)去を振り返り、新しいことを?qū)Wぶ (1) Javaの文字列を深く理解するnew String("abc") が呼び出されると、ヒープ メモリに 2 つの "abc" オブジェクトが作成され、str1 は「abc」オブジェクトと「abc」オブジェクトへの參照が定數(shù)プール內(nèi)に生成され、別の「abc」オブジェクトを指します。
Java がこのように設(shè)計(jì)されている理由については、前の記事ですでに説明しています。
String は Java で最も頻繁に使用されるデータ型であるため、プログラムのメモリを節(jié)約し、プログラムのパフォーマンスを向上させるためです。 , Java の設(shè)計(jì)者は、すべてのクラスで共有される文字列定數(shù)プール領(lǐng)域を公開(kāi)しており、各仮想マシンには文字列定數(shù)プールが 1 つだけあります。したがって、リテラル割り當(dāng)てを使用する場(chǎng)合、文字列が文字列定數(shù)プールにすでに存在する場(chǎng)合、オブジェクトはヒープ メモリに再作成されず、文字列定數(shù)プール內(nèi)のオブジェクトを直接ポイントします。

2. String の intern() メソッドString のメモリ割り當(dāng)てを理解した後、String の非常に重要なメソッド String.intern() を理解する必要があります。

読者の多くはこの方法についてあまり知らないかもしれませんが、重要ではないというわけではありません。まず intern() メソッドのソース コードを見(jiàn)てみましょう:

/**
     * 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.... これは実際にはネイティブ メソッドですが、問(wèn)題はありません。たとえソースが見(jiàn)えなくても

intern メソッドを呼び出すとき、文字列定數(shù)プールに String オブジェクトと等しい文字列が既に含まれている場(chǎng)合は、文字列定數(shù)プール內(nèi)の文字列への參照が直接返されます。それ以外の場(chǎng)合、この文字列オブジェクトに含まれる文字列が定數(shù)プールに追加され、このオブジェクトへの參照が返されます。

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

了解了intern方法的用途之后,來(lái)看一個(gè)簡(jiǎn)單的列子:

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ù)制代碼

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

過(guò)去を振り返り、新しいことを?qū)Wぶ (1) Javaの文字列を深く理解する

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

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

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

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

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

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

過(guò)去を振り返り、新しいことを?qū)Wぶ (1) Javaの文字列を深く理解する

2.改造例子,再看intern

上一節(jié)中我們通過(guò)一個(gè)例子認(rèn)識(shí)了intern()方法的作用,接下來(lái),我們對(duì)上述例子做一些修改:

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上會(huì)輸出什么結(jié)果?

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

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

過(guò)去を振り返り、新しいことを?qū)Wぶ (1) Javaの文字列を深く理解する

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

過(guò)去を振り返り、新しいことを?qū)Wぶ (1) Javaの文字列を深く理解する

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

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

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

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

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

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

過(guò)去を振り返り、新しいことを?qū)Wぶ (1) Javaの文字列を深く理解する

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

過(guò)去を振り返り、新しいことを?qū)Wぶ (1) Javaの文字列を深く理解する

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

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

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

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

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

前兩節(jié)我們認(rèn)識(shí)了String的內(nèi)存分配以及它的intern()方法,這兩節(jié)內(nèi)容其實(shí)都是對(duì)String內(nèi)存的分析。到目前為止,我們還并未認(rèn)識(shí)String類的結(jié)構(gòu)以及它的一些特性。那么本節(jié)內(nèi)容我們就此來(lái)分析。先通過(guò)一段代碼來(lá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接口,意味著它可以被序列化,同時(shí)方便我們排序。另外,String類還被聲明為了final類型,這意味著String類是不能被繼承的。而在其內(nèi)部維護(hù)了一個(gè)char數(shù)組,說(shuō)明String是通過(guò)char數(shù)組來(lái)實(shí)現(xiàn)的,同時(shí)我們注意到這個(gè)char數(shù)組也被聲明為了final,這也是我們常說(shuō)的String是不可變的原因。

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

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

過(guò)去を振り返り、新しいことを?qū)Wぶ (1) Javaの文字列を深く理解する

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

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

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

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

在本節(jié)內(nèi)容的開(kā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í)字符串的裁剪是通過(guò)實(shí)例化了一個(gè)新的String對(duì)象來(lái)實(shí)現(xiàn)的。所以,如果在項(xiàng)目中存在大量的字符串裁剪的代碼應(yīng)盡量避免使用String,而是使用性能更好的StringBuilder或StringBuffer來(lái)處理。

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

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

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

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

    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ù)制代碼

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

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

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

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

”+“操作符的實(shí)現(xiàn)原理由于”+“操作符是由JVM來(lái)完成的,我么無(wú)法直接看到代碼實(shí)現(xiàn)。不過(guò)Java為我們提供了一個(gè)javap的工具,可以幫助我們將Class文件進(jìn)行一個(gè)反匯編,通過(guò)匯編指令,大致可以看出”+“操作符的實(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é)果:

過(guò)去を振り返り、新しいことを?qū)Wぶ (1) Javaの文字列を深く理解する

注意圖中的”11:“行指令處實(shí)例化了一個(gè)StringBuilder,在"19:"行處調(diào)用了StringBuilder的append方法,并在第”27:"行處調(diào)用了String的toString()方法??梢?jiàn),JVM在進(jìn)行”+“字符串拼接時(shí)也是用了StringBuilder來(lái)實(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ù)制代碼

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

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ù)組拷貝,接下來(lái)又通過(guò)getChars方法再次進(jìn)行了數(shù)組拷貝,最后通過(guò)new實(shí)例化了String對(duì)象并返回。這也意味著每調(diào)用一次concat都會(huì)生成一個(gè)String對(duì)象,但相比”+“操作符卻省去了toString方法。因此,其性能要比”+“操作符好上不少。

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

四、總結(jié)

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


以上が過(guò)去を振り返り、新しいことを?qū)Wぶ (1) Javaの文字列を深く理解するの詳細(xì)內(nèi)容です。詳細(xì)については、PHP 中國(guó)語(yǔ) Web サイトの他の関連記事を參照してください。

このウェブサイトの聲明
この記事の內(nèi)容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰屬します。このサイトは、それに相當(dāng)する法的責(zé)任を負(fù)いません。盜作または侵害の疑いのあるコンテンツを見(jiàn)つけた場(chǎng)合は、admin@php.cn までご連絡(luò)ください。

ホットAIツール

Undress AI Tool

Undress AI Tool

脫衣畫像を無(wú)料で

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード寫真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

寫真から衣服を削除するオンライン AI ツール。

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無(wú)料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡(jiǎn)単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無(wú)料のコードエディター

SublimeText3 中國(guó)語(yǔ)版

SublimeText3 中國(guó)語(yǔ)版

中國(guó)語(yǔ)版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強(qiáng)力な PHP 統(tǒng)合開(kāi)発環(huán)境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開(kāi)発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

PHPコメントを書くためのヒント PHPコメントを書くためのヒント Jul 18, 2025 am 04:51 AM

PHPコメントを書くための鍵は、目的と仕様を明確にすることです。コメントは、「何が行われたのか」ではなく「なぜ」を説明する必要があり、冗長(zhǎng)性や単純さを避けてください。 1.読みやすさとツールの互換性を向上させるために、クラスおよびメソッドの説明にdocblock(/*/)などの統(tǒng)合形式を使用します。 2。JSジャンプを手動(dòng)で出力する必要がある理由など、ロジックの背後にある理由を強(qiáng)調(diào)します。 3.複雑なコードの前に概要説明を追加し、手順でプロセスを説明し、全體的なアイデアを理解するのに役立ちます。 4. TodoとFixmeを合理的に使用して、To Doアイテムと問(wèn)題をマークして、その後の追跡とコラボレーションを促進(jìn)します。優(yōu)れた注釈は、通信コストを削減し、コードメンテナンスの効率を向上させることができます。

効果的なPHPコメントを書く 効果的なPHPコメントを書く Jul 18, 2025 am 04:44 AM

コメントは、古いインターフェイスとの互換性やサードパーティの制限など、機(jī)能ではなくコードの存在の理由を説明したいため、不注意にすることはできません。コメントしなければならない領(lǐng)域には、複雑な條件付き判斷、特別なエラー処理ロジック、一時(shí)的なバイパス制限が含まれます。コメントを書くためのより実用的な方法は、シーンに基づいてシングルラインのコメントを選択したり、コメントをブロックすることです。ドキュメントブロックコメントを使用して、関數(shù)、クラス、ファイルの開(kāi)始時(shí)にパラメーターと返品値を説明し、コメントを更新します。複雑なロジックについては、前のロジックにラインを追加して、全體的な意図を要約できます。同時(shí)に、コードを封印するためにコメントを使用しないでください。バージョン制御ツールを使用します。

コメントで読みやすさを向上させます コメントで読みやすさを向上させます Jul 18, 2025 am 04:46 AM

良いコメントを書くための鍵は、コードの読みやすさを改善するために「何が行われたか」ではなく「なぜ」を説明することです。 1。コメントは、価値の選択や処理の背後にある考慮事項(xiàng)など、論理的な理由を説明する必要があります。 2。複雑なロジックに段落注釈を使用して、関數(shù)またはアルゴリズムの全體的な考え方を要約します。 3.コードとの一貫性を確保し、誤解を招くことを避け、必要に応じて時(shí)代遅れのコンテンツを削除するために、コメントを定期的に維持します。 4.コードをレビューする際にコメントを同期して確認(rèn)し、コードコメントの負(fù)擔(dān)を軽減するためにドキュメントを介してパブリックロジックを記録します。

PHP開(kāi)発環(huán)境のセットアップ PHP開(kāi)発環(huán)境のセットアップ Jul 18, 2025 am 04:55 AM

最初のステップは、統(tǒng)合環(huán)境パッケージXAMPPまたはMAMPを選択してローカルサーバーを構(gòu)築することです。 2番目のステップは、プロジェクトのニーズに応じて適切なPHPバージョンを選択し、複數(shù)のバージョンの切り替えを構(gòu)成することです。 3番目のステップは、editorとしてvscodeまたはphpstormを選択し、xdebugでデバッグすることです。さらに、開(kāi)発を支援するために、作曲家、PHP_CODESNIFFER、PHPUNIT、およびその他のツールをインストールする必要があります。

効果的なPHPコメント 効果的なPHPコメント Jul 18, 2025 am 04:33 AM

PHPコメントを書くための鍵は、明確で、便利で簡(jiǎn)潔です。 1。コメントは、複雑な條件付き判斷の論理的目的を説明するなど、コード自體を説明するのではなく、コードの背後にある意図を説明する必要があります。 2.読みやすさを改善するために、魔法の値、古いコード互換性、APIインターフェイスなどの重要なシナリオにコメントを追加します。 3.コードコンテンツの重複を避け、簡(jiǎn)潔かつ具體的に保ち、PHPDOCなどの標(biāo)準(zhǔn)形式を使用します。 4。コメントは、正確性を確保するためにコードと同期して更新する必要があります。他の人の観點(diǎn)から良いコメントを考えるべきであり、理解のコストを削減し、ナビゲーションデバイスを理解するコードを理解する必要があります。

PHP変數(shù)の理解 PHP変數(shù)の理解 Jul 17, 2025 am 04:11 AM

PHP変數(shù)は$で始まり、命名は數(shù)字から始めることができず、ケースに敏感であるなど、ルールに従う必要があります。変數(shù)の範(fàn)囲は、ローカル、グローバル、ハイパーグローバルに分割されます。グローバル変數(shù)はグローバルを使用してアクセスできますが、パラメーターで渡すことをお?jiǎng)幛幛筏蓼?。可変変?shù)と參照割り當(dāng)ては注意して使用する必要があります。変數(shù)はデータを保存するための基礎(chǔ)であり、それらのルールとメカニズムを正しく習(xí)得することは開(kāi)発にとって重要です。

構(gòu)文をコメントするPHP 構(gòu)文をコメントするPHP Jul 18, 2025 am 04:56 AM

PHPコメントを使用するには3つの一般的な方法があります。単一ラインコメントは、現(xiàn)在の行の説明のために//などのコードロジックを簡(jiǎn)単に説明するのに適しています。マルチラインコメント/*...*/関數(shù)またはクラスの詳細(xì)な説明に適しています。ドキュメントコメントdocblockは /**で起動(dòng)して、IDEの迅速な情報(bào)を提供します。それを使用する場(chǎng)合、ナンセンスを避け、同期して更新し続け、コメントを使用してコードを長(zhǎng)時(shí)間ブロックしないでください。

PHP変數(shù)タイプの理解 PHP変數(shù)タイプの理解 Jul 17, 2025 am 04:12 AM

PHPには8つの変數(shù)タイプがあり、一般的に使用される整數(shù)、フロート、ストリング、ブール、アレイ、オブジェクト、nullおよびリソースが含まれます。変數(shù)タイプを表示するには、getType()またはis_type()シリーズ関數(shù)を使用します。 PHPは自動(dòng)的にタイプを変換しますが、===を使用してキーロジックを厳密に比較することをお?jiǎng)幛幛筏蓼?。手?dòng)変換は、(int)、(文字列)などの構(gòu)文に使用できますが、情報(bào)が失われる可能性があることに注意してください。

See all articles