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

目錄
一、從String字串的記憶體分配說起
2.JDK7中的記憶體分配
二、String的intern()方法
1.一個關于intern()的簡單例子
2.改造例子,再看intern
2).JDK6的運行結果分析
三、String類的結構及特性分析
1.不同JDK版本之間String的差異
2.String字符串的裁剪、拼接等操作分析
(1)String的substring實現(xiàn)
(2)String的字符串拼接實現(xiàn)
1)字符串拼接方案性能對比
2)三種字符串拼接方案原理分析
四、總結
首頁 Java Java基礎 溫故知新(1)深入認識Java中的字串

溫故知新(1)深入認識Java中的字串

Sep 18, 2020 pm 05:32 PM
java 字串

溫故知新(1)深入認識Java中的字串

相關學習推薦:java基礎教學

初學Java時我們已經(jīng)知道Java中可以分為兩大資料類型,分別為基本資料型別和引用資料型別。而在這兩大資料型別中有一個特殊的資料型別String,String屬於引用資料型別,但又有區(qū)別於其它的引用資料型態(tài)。可以說它是資料型別中的一朵奇葩。那麼,本篇文章我們就來深入的認識Java中的String字串。

一、從String字串的記憶體分配說起

上一篇文章《溫故知新--你不知道的JVM記憶體分配》詳細的分析了JVM的記憶體模型。在常數(shù)池部分我們了解了三種常數(shù)池,分別為:字串常數(shù)池、Class檔案常數(shù)池以及運行時常數(shù)池。而字串的記憶體分配則和字串常數(shù)池有著莫大的關係。

我們知道,實例化一個字串可以透過兩種方法來實現(xiàn),第一種最常用的是透過字面量賦值的方式,另一種是透過建構方法傳參的方式。程式碼如下:

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

這兩種方式在記憶體分配上有什麼不同呢? 相信大家在初學Java的時候老師都有給我們講解過:

1.通過字面量賦值的方式創(chuàng)建String,只會在字串常數(shù)池中產(chǎn)生String物件。 2.透過建構方法傳入String參數(shù)的方式會在堆疊記憶體和字串常數(shù)池中各產(chǎn)生一個String對象,並將堆疊記憶體上String的參考放入堆疊。

這樣的回答正確嗎?至少在現(xiàn)在看來並不完全正確,因為它完全取決於所使用的Java版本。上一篇文章《溫故知新--你不知道的JVM記憶體分配》談到HotSpot虛擬機在不同的JDK上對於字串常數(shù)池的實現(xiàn)是不同的,摘錄如下:

在JDK7以前,字串常數(shù)池在方法區(qū)(永久代)中,此時常數(shù)池中存放的是字串物件。而在JDK7中,字串常數(shù)池從方法區(qū)遷移到了堆內(nèi)存,同時將字串物件存到了Java堆,字串常數(shù)池中只是存入了字串物件的引用。

這句話該怎麼理解呢?我們以String str1=new String("abc")為例來分析:

1.JDK6中的記憶體分配

先來分析JDK6的記憶體分配情況,如下圖所示:

溫故知新(1)深入認識Java中的字串

當呼叫new String("abc")後,會在Java堆與常數(shù)池中各產(chǎn)生一個「abc」物件。同時,將str1指向堆中的「abc」物件。

2.JDK7中的記憶體分配

而在JDK7及以後版本中,由於字串常數(shù)池被移到了堆內(nèi)存,所以記憶體分配方式也有所不同,如下圖所示:

溫故知新(1)深入認識Java中的字串

當呼叫了new String("abc")後,會在堆記憶體中建立兩個「abc"對象,str1指向其中一個”abc"對象,而常數(shù)池中則會產(chǎn)生一個“abc"對象的引用,並指向另一個”abc"對象。

至於Java中為什麼要這麼設計,我們在上篇文章中也已經(jīng)解釋了: 因為String是Java中使用最頻繁的一種資料類型,為了節(jié)省程式記憶體提高程式效能, Java的設計者開闢了一塊字串常數(shù)池區(qū)域,這塊區(qū)域是是所有類別共享的,每個虛擬機器只有一個字串常數(shù)池。因此,在使用字面量方式賦值的時候,如果字串常數(shù)池中已經(jīng)有了該字串,則不會在堆內(nèi)存中重新創(chuàng)建對象,而是直接將其指向了字串常數(shù)池中的對象。

二、String的intern()方法

在了解String的記憶體分配之後,我們需要再來認識String中一個很重要的方法:String.intern() 。

很多讀者可能對於這個方法並不是太了解,但不代表他不重要。我們先來看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();復制代碼

emmmmm....居然是native方法,不過沒關係,即使看不到原始碼我們也能從其註解中得到一些資訊:當呼叫intern方法的時候,如果字串常數(shù)池中已經(jīng)包含了一個等於該String物件的字串,則直接傳回字串常數(shù)池中該字串的參考。否則,會將該字串物件包含的字串新增至常數(shù)池,並傳回此物件的參考。

1.一個關于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));
    }
}復制代碼

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

溫故知新(1)深入認識Java中的字串

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

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

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

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

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

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

溫故知新(1)深入認識Java中的字串

2.改造例子,再看intern

上一節(jié)中我們通過一個例子認識了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)); 
    }
}復制代碼

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

1).JDK8的運行結果分析

我們先來看下我們先來看下JDK8的運行結果:

溫故知新(1)深入認識Java中的字串

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

溫故知新(1)深入認識Java中的字串

String str1=new String("he")+new String("llo"); 這行代碼中new String("he")和new String("llo")會在堆上生成四個對象,因為與本例無關,所以圖上沒有畫出,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"對象的應用放入字符串常量池中。

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

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

2).JDK6的運行結果分析

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

溫故知新(1)深入認識Java中的字串

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

溫故知新(1)深入認識Java中的字串

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

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

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

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

三、String類的結構及特性分析

前兩節(jié)我們認識了String的內(nèi)存分配以及它的intern()方法,這兩節(jié)內(nèi)容其實都是對String內(nèi)存的分析。到目前為止,我們還并未認識String類的結構以及它的一些特性。那么本節(jié)內(nèi)容我們就此來分析。先通過一段代碼來大致了解一下String類的結構(代碼取自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
        //  ...}復制代碼

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

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

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

溫故知新(1)深入認識Java中的字串

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

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

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

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

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

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

關于substring的實現(xiàn),其實我們直接深入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);
        }復制代碼

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

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

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

關于字符串的拼接有很多實現(xià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";
            }
    }復制代碼

使用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";
            }
    }復制代碼

使用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");
            }
    }復制代碼

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

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

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

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

”+“操作符的實現(xiàn)原理由于”+“操作符是由JVM來完成的,我么無法直接看到代碼實現(xiàn)。不過Java為我們提供了一個javap的工具,可以幫助我們將Class文件進行一個反匯編,通過匯編指令,大致可以看出”+“操作符的實現(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";
            }
    }復制代碼

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

溫故知新(1)深入認識Java中的字串

注意圖中的”11:“行指令處實例化了一個StringBuilder,在"19:"行處調用了StringBuilder的append方法,并在第”27:"行處調用了String的toString()方法??梢?,JVM在進行”+“字符串拼接時也是用了StringBuilder來實現(xiàn)的,但為什么與直接使用StringBuilder的差距那么大呢?其實,只要我們將上邊代碼轉換成虛擬機優(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();
            }
    }復制代碼

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

String的concat方法的實現(xià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);
    }復制代碼

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

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

四、總結

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


以上是溫故知新(1)深入認識Java中的字串的詳細內(nèi)容。更多資訊請關注PHP中文網(wǎng)其他相關文章!

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發(fā)現(xiàn)涉嫌抄襲或侵權的內(nèi)容,請聯(lián)絡admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

編寫有效的PHP評論 編寫有效的PHP評論 Jul 18, 2025 am 04:44 AM

註釋不能馬虎是因為它要解釋代碼存在的原因而非功能,例如兼容老接口或第三方限制,否則看代碼的人只能靠猜。必須加註釋的地方包括複雜的條件判斷、特殊的錯誤處理邏輯、臨時繞過的限制。寫註釋更實用的方法是根據(jù)場景選擇單行註釋或塊註釋,函數(shù)、類、文件開頭用文檔塊註釋說明參數(shù)與返回值,並保持註釋更新,對複雜邏輯可在前面加一行概括整體意圖,同時不要用註釋封存代碼而應使用版本控制工具。

撰寫PHP評論的提示 撰寫PHP評論的提示 Jul 18, 2025 am 04:51 AM

寫好PHP註釋的關鍵在於明確目的與規(guī)範,註釋應解釋“為什麼”而非“做了什麼”,避免冗餘或過於簡單。 1.使用統(tǒng)一格式,如docblock(/*/)用於類、方法說明,提升可讀性與工具兼容性;2.強調邏輯背後的原因,如說明為何需手動輸出JS跳轉;3.在復雜代碼前添加總覽性說明,分步驟描述流程,幫助理解整體思路;4.合理使用TODO和FIXME標記待辦事項與問題,便於後續(xù)追蹤與協(xié)作。好的註釋能降低溝通成本,提升代碼維護效率。

通過評論提高可讀性 通過評論提高可讀性 Jul 18, 2025 am 04:46 AM

寫好註釋的關鍵在於說明“為什麼”而非僅“做了什麼”,提升代碼可讀性。 1.註釋應解釋邏輯原因,例如值選擇或處理方式背後的考量;2.對複雜邏輯使用段落式註釋,概括函數(shù)或算法的整體思路;3.定期維護註釋確保與代碼一致,避免誤導,必要時刪除過時內(nèi)容;4.在審查代碼時同步檢查註釋,並通過文檔記錄公共邏輯以減少代碼註釋負擔。

有效的PHP評論 有效的PHP評論 Jul 18, 2025 am 04:33 AM

寫好PHP註釋的關鍵在於清晰、有用且簡潔。 1.註釋應說明代碼背後的意圖而非僅描述代碼本身,如解釋複雜條件判斷的邏輯目的;2.在魔術值、舊代碼兼容、API接口等關鍵場景添加註釋以提升可讀性;3.避免重複代碼內(nèi)容,保持簡潔具體,並使用標準格式如PHPDoc;4.註釋需與代碼同步更新,確保準確性。好的註釋應站在他人角度思考,降低理解成本,成為代碼的理解導航儀。

了解PHP變量 了解PHP變量 Jul 17, 2025 am 04:11 AM

PHP變量以$開頭,命名需遵循規(guī)則,如不能以數(shù)字開頭、區(qū)分大小寫;變量作用域分為局部、全局和超全局;使用global可訪問全局變量,但建議用參數(shù)傳遞;可變變量和引用賦值需謹慎使用。變量是存儲數(shù)據(jù)的基礎,正確掌握其規(guī)則和機制對開發(fā)至關重要。

PHP開發(fā)環(huán)境設置 PHP開發(fā)環(huán)境設置 Jul 18, 2025 am 04:55 AM

第一步選擇集成環(huán)境包XAMPP或MAMP搭建本地服務器;第二步根據(jù)項目需求選擇合適的PHP版本並配置多版本切換;第三步選用VSCode或PhpStorm作為編輯器並搭配Xdebug進行調試;此外還需安裝Composer、PHP_CodeSniffer、PHPUnit等工具輔助開發(fā)。

PHP評論語法 PHP評論語法 Jul 18, 2025 am 04:56 AM

PHP註釋有三種常用方式:單行註釋適合簡要說明代碼邏輯,如//或#用於當前行解釋;多行註釋/*...*/適合詳細描述函數(shù)或類的作用;文檔註釋DocBlock以/**開頭,為IDE提供提示信息。使用時應避免廢話、保持同步更新,並勿長期用註釋屏蔽代碼。

PHP比較操作員 PHP比較操作員 Jul 18, 2025 am 04:57 AM

PHP比較運算符需注意類型轉換問題。 1.使用==僅比較值,會進行類型轉換,如1=="1"為true;2.使用===需值與類型均相同,如1==="1"為false;3.大小比較可作用於數(shù)值和字符串,如"apple"

See all articles