แตกต่างกันระหว่าง parseInt () และ valueOf () ใน java?


443

เป็นวิธีการที่parseInt()แตกต่างจากvalueOf()?

พวกเขาดูเหมือนจะทำสิ่งเดียวกันกับผม (ยังไปสำหรับparseFloat(), parseDouble(), parseLong()ฯลฯ วิธีการที่พวกเขาแตกต่างจากLong.valueOf(string)?

นอกจากนี้หนึ่งในสิ่งเหล่านี้เป็นที่นิยมและใช้บ่อยโดยการประชุม?

คำตอบ:


411

ดี API สำหรับการInteger.valueOf(String)ไม่แน่นอนบอกว่าถูกตีความว่าเป็นถ้ามันถูกมอบให้กับString Integer.parseInt(String)แต่valueOf(String)ส่งกลับวัตถุในขณะที่ผลตอบแทนดั้งเดิมnew Integer()parseInt(String)int

หากคุณต้องการเพลิดเพลินไปกับผลประโยชน์การแคชที่เป็นไปได้ของInteger.valueOf(int)คุณยังสามารถใช้สิ่งที่อุจาดนัยน์ตานี้:

Integer k = Integer.valueOf(Integer.parseInt("123"))

ตอนนี้ถ้าสิ่งที่คุณต้องการเป็นวัตถุและไม่ดั้งเดิมแล้วใช้valueOf(String)อาจจะน่าสนใจกว่าการทำวัตถุใหม่จากparseInt(String)เพราะอดีตเป็นอย่างต่อเนื่องในปัจจุบันทั่วInteger, Long, Doubleฯลฯ


8
มีความแตกต่างระหว่างประสิทธิภาพหรือความจำระหว่างสองวิธีหรือไม่?
โลแกน

90
Integer.valueOf(Integer.parseInt("123"))ไม่ได้รับประโยชน์มากกว่าInteger.valueOf("123")หรือInteger.valueOf(123)นอกเหนือจากรอบการสูญเสียและขนาดของโปรแกรมของคุณ
Thomas Eding

9
มีความแตกต่าง - วัตถุใหม่ (อาจ) จัดสรรโดย valueOf มาพร้อมกับค่าใช้จ่าย (หน่วยความจำสำหรับวัตถุ, การจัดการ, GC) ในขณะที่ int ธรรมดาคือ "เบา" มาก (สำหรับค่าทั่วไปส่วนใหญ่คุณจะได้รับการอ้างอิงถึงออบเจกต์ที่มีอยู่แล้วซึ่งจะช่วยนิด ๆ หน่อย ๆ )
foo

14
Integer.valueOf(String)Integer.valueOf(int)ไม่ตรงกับแคชเดียวกับ ในความเป็นจริงมันถูกนำมาใช้เป็นInteger.valueOf(Integer.parseInt(…))...
Holger

11
@Khez intมันเป็นไปไม่ได้ให้มันกลับมาดั้งเดิม ลายเซ็นบอกว่ามันส่งกลับIntegerและนั่นคือสิ่งที่มันทำ คำตอบนี้เป็นเพียงบางส่วนไม่ถูกต้องเมื่อมันบอกว่าจะส่งกลับ Integer'ใหม่' นั่นไม่ใช่สิ่งที่พูดใน Javadoc Integerมันมีอิสระที่จะกลับแคช
มาร์ควิสแห่ง Lorne

73

จากฟอรั่มนี้ :

parseInt()ส่งคืนชนิดจำนวนเต็มดั้งเดิม ( int ) โดยที่valueOfส่งคืน java.lang.Integerซึ่งเป็นตัวแทนวัตถุของจำนวนเต็ม มีสถานการณ์ที่คุณอาจต้องการวัตถุจำนวนเต็มแทนที่จะเป็นชนิดดั้งเดิม

แน่นอนความแตกต่างที่ชัดเจนอีกอย่างหนึ่งคือintValueเป็นวิธีการอินสแตนซ์โดยที่parseIntเป็นวิธีการคงที่


9
มูลค่าการกล่าวขวัญ: รุ่น valueOf จะใช้พูลอ้างอิงภายในเพื่อส่งคืนวัตถุ SAME สำหรับค่าที่กำหนดไม่ใช่เพียงอินสแตนซ์อื่นที่มีค่าภายในเหมือนกัน ซึ่งหมายความว่าได้รับสอง Longs กลับมาในลักษณะนี้ a.equals (ข) == จริงและ == ขเป็นจริง
basszero

จากการพิสูจน์ต่อไปลงคุณถูกต้องสำหรับเวอร์ชั่น String ฉันคิดว่ารุ่นดั้งเดิม Long.valueOf (5) จะส่งคืนวัตถุเดียวกันเสมอ รุ่นสตริงส่งคืนวัตถุใหม่รุ่นดั้งเดิมจะส่งคืนวัตถุเดียวกัน
basszero

1
@bassezero นอกจากนี้พูลนั้นมีขีด จำกัด ฉันคิดว่ามันเป็น -127 ถึง 127
OscarRyz

1
ขนาดของพูลอ้างอิงเป็นตัวอย่างจริงของรายละเอียดการใช้งาน มันอาจเพิ่มขนาดในแพทช์รีลีสและคุณไม่ควรพึ่งพาสิ่งใดเลย
Donal Fellows

@OscarRyz ที่จริงแล้วคือ -128 ถึง 127 โปรดทราบว่า JVM เสนอพารามิเตอร์เพื่อตั้งค่าขอบเขตสูงสุดที่สูงกว่าสำหรับแคช อย่างไรก็ตามคุณไม่สามารถกำหนดขอบเขตต่ำสุดได้อีก: stackoverflow.com/questions/29633158/ …
Jean-François Savard

36
Integer.valueOf(s)

เหมือนกับ

new Integer(Integer.parseInt(s))

ความแตกต่างจะvalueOf()ส่งกลับIntegerและparseInt()ส่งกลับint(ชนิดดั้งเดิม) นอกจากนี้โปรดทราบว่าvalueOf()สามารถส่งคืนIntegerอินสแตนซ์ที่แคชไว้ซึ่งอาจทำให้เกิดผลลัพธ์ที่สับสนซึ่งผลลัพธ์ของ==การทดสอบนั้นดูเหมือนจะถูกต้องเป็นระยะ ก่อนการautoboxingอาจมีความแตกต่างในด้านความสะดวกสบายหลังจาก java 1.5 มันไม่สำคัญเลย

นอกจากนี้ยังInteger.parseInt(s)สามารถใช้ประเภทข้อมูลดั้งเดิมได้เช่นกัน


4
valueOf () สามารถส่งคืนวัตถุเดียวกันสำหรับการโทรติดต่อกันด้วยอาร์กิวเมนต์เดียวกัน (และจำเป็นสำหรับอาร์กิวเมนต์ระหว่าง -128 ถึง 127 รวม) new Integer () จะสร้างวัตถุใหม่เสมอ
Adam Rosenfield

อันไหนที่ใช้บ่อยกว่า? ฉันควรใช้อันไหนดีที่สุด
คลิกโหวต

3
หากคุณต้องการ int ให้ใช้ parseInt () ถ้าคุณต้องการ Integer ให้ใช้ valueOf ()
matt b

@Joan d Silva จากบรรทัดสุดท้ายของคุณฉันคิดว่า Integer.parseInt สามารถใช้เป็นสตริงได้ในขณะที่ Integer.ValueOf (s) สามารถใช้ทั้ง int และสตริงเป็นอาร์กิวเมนต์อินพุต
Pratik

14

ดูแหล่งข้อมูล Java: valueOfกำลังใช้งานparseInt:

/**
 * Parses the specified string as a signed decimal integer value.
 *
 * @param string
 *            the string representation of an integer value.
 * @return an {@code Integer} instance containing the integer value
 *         represented by {@code string}.
 * @throws NumberFormatException
 *             if {@code string} cannot be parsed as an integer value.
 * @see #parseInt(String)
 */
public static Integer valueOf(String string) throws NumberFormatException {
    return valueOf(parseInt(string));
}

parseInt ผลตอบแทน int

/**
 * Parses the specified string as a signed decimal integer value. The ASCII
 * character \u002d ('-') is recognized as the minus sign.
 *
 * @param string
 *            the string representation of an integer value.
 * @return the primitive integer value represented by {@code string}.
 * @throws NumberFormatException
 *             if {@code string} cannot be parsed as an integer value.
 */
public static int parseInt(String string) throws NumberFormatException {
    return parseInt(string, 10);
}

6

Integer.parseInt สามารถคืนค่า int เป็นชนิดเนทีฟ

Integer.valueOf อาจจำเป็นต้องจัดสรรอ็อบเจกต์ Integer นอกเสียจากว่าจำนวนเต็มนั้นจะเป็นหนึ่งในวัตถุที่ถูกจัดสรรล่วงหน้า ค่าใช้จ่ายนี้มากขึ้น

หากคุณต้องการประเภทเนทิฟเพียงอย่างเดียวให้ใช้ parseInt หากคุณต้องการวัตถุใช้ valueOf

นอกจากนี้เนื่องจากการจัดสรรที่เป็นไปได้นี้การล็อกอัตโนมัติจึงไม่ใช่สิ่งที่ดีในทุกด้าน มันสามารถชะลอสิ่งต่างๆ


1

รูปแบบการแยกวิเคราะห์ * ส่งคืนชนิดดั้งเดิมและรุ่น valueOf ส่งคืนวัตถุ ฉันเชื่อว่ารุ่น valueOf จะใช้พูลอ้างอิงภายในเพื่อส่งคืนวัตถุ SAME สำหรับค่าที่กำหนดไม่ใช่แค่อินสแตนซ์อื่นที่มีค่าภายในเหมือนกัน


จริงๆแล้วไม่จริงเลย ฉันคิดอย่างนั้นในตอนแรก แต่ Javadocs สำหรับ Integer.valueOf (String) ระบุไว้อย่างชัดเจนว่าเทียบเท่ากับ Integer ใหม่ (Integer.parseInt (String)) Integer.valueOf (int) ทำแคชแน่นอน
Michael Myers

คุณถูกต้องสำหรับเวอร์ชั่น String ฉันคิดถึงเวอร์ชันดั้งเดิม Long.valueOf (5) จะส่งคืนวัตถุเดียวกันเสมอ
basszero

1

เนื่องจากคุณอาจใช้ jdk1.5 + และมีการแปลงเป็น int โดยอัตโนมัติ ดังนั้นในโค้ดของคุณมันจะคืนค่า Integer แรกจากนั้นแปลงเป็น int โดยอัตโนมัติ

รหัสของคุณเหมือนกับ

int abc = new Integer(123);

0

หากคุณตรวจสอบคลาส Integer คุณจะพบว่าค่าของการโทร parseInt วิธีการ ข้อแตกต่างที่สำคัญคือการแคชเมื่อคุณเรียกใช้ valueof API มันแคชถ้าค่าอยู่ระหว่าง -128 ถึง 127 กรุณาหาลิงค์ด้านล่างสำหรับข้อมูลเพิ่มเติม

http://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html


0

public static Integer valueOf (String s)

  1. อาร์กิวเมนต์ถูกตีความว่าแสดงถึงจำนวนเต็มฐานสิบที่ลงลายมือชื่อเหมือนกับว่ามีการมอบอาร์กิวเมนต์ให้กับวิธี parseInt (java.lang.String)
  2. ผลลัพธ์ที่ได้คือวัตถุจำนวนเต็มที่แสดงถึงค่าจำนวนเต็มที่ระบุโดยสตริง

  3. กล่าวอีกนัยหนึ่งวิธีนี้ส่งคืนวัตถุจำนวนเต็มเท่ากับค่าของ: จำนวนเต็มใหม่ (จำนวนเต็ม.parseInt)


0
  • valueOf - แปลงเป็นคลาส Wrapper
  • parseInt - แปลงเป็นชนิดดั้งเดิม

Integer.parseInt ยอมรับเฉพาะ String และส่งคืนชนิดจำนวนเต็มดั้งเดิม (int)

   public static int parseInt(String s) throws NumberFormatException {
        return parseInt(s,10);
    }

Iteger.valueOf ยอมรับ int และ String ถ้า value เป็น String valueOf จะแปลงเป็น int อย่างง่ายโดยใช้ parseInt และส่งคืน Integer ใหม่ถ้าอินพุตน้อยกว่า -128 หรือมากกว่า 127 ถ้าอินพุตอยู่ในช่วง (-128 - 127) จะส่งคืนออบเจ็กต์ Integer เสมอจาก IntegerCache ภายใน ชั้น Integer รักษาชั้น IntegerCache คงที่ซึ่งทำหน้าที่เป็นแคชและเก็บวัตถุจำนวนเต็มจาก -128 ถึง 127 และนั่นคือเหตุผลที่เมื่อเราพยายามที่จะได้รับวัตถุจำนวนเต็มสำหรับ 127 (ตัวอย่าง) เรามักจะได้รับวัตถุเดียวกัน

Iteger.valueOf(200)จะให้ Integer ใหม่จาก 200 เหมือนnew Integer(200) Iteger.valueOf(127)เป็นเหมือนInteger = 127;

หากคุณเคยชินในการแปลง String Iteger.valueOfการใช้จำนวนเต็ม

หากคุณเคยชินในการแปลง String Integer.parseIntการใช้งานที่ง่าย มันทำงานได้เร็วขึ้น

  public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

  public static Integer valueOf(String s) throws NumberFormatException {
        return Integer.valueOf(parseInt(s, 10));
  }

  private static class IntegerCache {
      static final int low = -128;
      static final int high;
      static final Integer cache[];

    static {
        // high value may be configured by property
        int h = 127;
        String integerCacheHighPropValue =
            sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
        if (integerCacheHighPropValue != null) {
            try {
                int i = parseInt(integerCacheHighPropValue);
                i = Math.max(i, 127);
                // Maximum array size is Integer.MAX_VALUE
                h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
            } catch( NumberFormatException nfe) {
                // If the property cannot be parsed into an int, ignore it.
            }
        }
        high = h;

        cache = new Integer[(high - low) + 1];
        int j = low;
        for(int k = 0; k < cache.length; k++)
            cache[k] = new Integer(j++);

        // range [-128, 127] must be interned (JLS7 5.1.7)
        assert IntegerCache.high >= 127;
    }

    private IntegerCache() {}
  }

และเปรียบเทียบ Integer.valueOf (127) == Integer.valueOf (127) คืนค่าจริง

Integer a = 127; // Compiler converts this line to Integer a = Integer.valueOf(127);
Integer b = 127; // Compiler converts this line to Integer b = Integer.valueOf(127);
a == b; // return true 

เพราะใช้วัตถุจำนวนเต็มที่มีการอ้างอิงเดียวกันจากแคช

แต่ Integer.valueOf (128) == Integer.valueOf (128) เป็นเท็จเพราะ 128 อยู่นอกช่วง IntegerCache และส่งคืน Integer ใหม่ดังนั้นวัตถุจะมีการอ้างอิงที่แตกต่างกัน


โปรดอย่าใช้การจัดรูปแบบตัวหนาที่ไม่เหมาะสม: มันทำให้การอ่านโพสต์ของคุณลดลง
โซอี้

-2
  1. ในกรณีของ ValueOf -> มันกำลังสร้างออบเจ็กต์ Integer ไม่ใช่ประเภทดั้งเดิมและไม่ใช่วิธีการคงที่
  2. ในกรณีของ ParseInt.ParseFloat -> มันจะคืนค่าชนิดดั้งเดิมตามลำดับ และเป็นวิธีการคงที่

เราควรใช้คนใดคนหนึ่งขึ้นอยู่กับความต้องการของเรา ในกรณีของ ValueOf เนื่องจากเป็นอินสแตนซ์ของวัตถุ มันจะกินทรัพยากรมากขึ้นถ้าเราต้องการคุณค่าของข้อความบางส่วนเท่านั้นเราควรใช้ parseInt, parseFloat เป็นต้น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.