Java รองรับโครงสร้างหรือไม่


95

Java มีแอนะล็อกของ C ++ หรือไม่struct:

struct Member {
  string FirstName; 
  string LastName;  
  int BirthYear; 
};

ฉันต้องใช้ประเภทข้อมูลของฉันเอง


สำหรับผู้ที่คัดลอกตัวอักษรมากเกินไป: ฟิลด์ใน Java จริงๆต้องเริ่มต้นด้วยตัวอักษรตัวพิมพ์เล็กดังนั้นfirstName, lastNameและbirthYear(หรือyearOfBirthของหลักสูตร)
Maarten Bodewes

คำตอบ:


51

Java ไม่มีโครงสร้างแน่นอน :) แต่สิ่งที่คุณอธิบายที่นี่ดูเหมือนคลาส JavaBean


31
ชั้นเรียนที่มีตัวแปรสาธารณะเท่านั้นที่ดูเหมือนเป็นตัวถ่วง
mglauche

10
เราจะมีบันทึก 9 ปีหลังจากคำตอบนี้ใน Java 14 มันน่าขบขันว่าเวลาผ่านไปเร็วแค่ไหน
George Leung

ความแตกต่างที่สำคัญอย่างหนึ่งระหว่างคลาสและโครงสร้างคือพฤติกรรมในหน่วยความจำ ในแง่นี้คำตอบนี้ผิด Java ไม่มีอะไรที่ทำงานเหมือนโครงสร้าง แต่หวังว่าจะมีinline classในอนาคตอันใกล้ซึ่งฉันเชื่อว่าเป็นเหมือนโครงสร้าง
Will Calderwood

ถั่วมีคุณสมบัติ (เช่น getters และ setters) และในปัจจุบันมักมีการใส่คำอธิบายประกอบเพื่อให้เป็นไปตามข้อกำหนดของ bean
Maarten Bodewes

88

สิ่งที่เทียบเท่าใน Java กับโครงสร้างจะเป็น

class Member
{
    public String FirstName; 
    public String LastName;  
    public int    BirthYear; 
 };

และไม่มีอะไรผิดปกติในสถานการณ์ที่ถูกต้อง เช่นเดียวกับใน C ++ ในแง่ของเวลาที่คุณใช้ข้อต่อโครงสร้างเมื่อใดที่คุณใช้คลาสที่มีข้อมูลที่ห่อหุ้ม


22
ฉันจะใช้คลาสประเภท "POD" ใน java ในสถานการณ์เดียวกับที่ฉันทำใน C ++ "ออบเจ็กต์มูลค่า" เกิดขึ้นใน J2EE ซึ่งคุณมีวิธีการที่ส่งคืนค่าหลายค่าพร้อมกัน ไม่มีประเด็นในการห่อหุ้มข้อมูลด้วยเมธอด getter และ setter เพียงแค่ทำให้ฟิลด์สาธารณะ - สั้นลงและอธิบายได้มากขึ้น อะไรก็ตามที่ "เหมาะสม" ฉันมักจะห่อหุ้มในสิ่งเดียวกับที่ฉันทำใน C ++ ดังนั้นฉันจึงยืนหยัดตามความคิดเห็นเดิมของฉัน แต่มันเป็นตัวเลือกสไตล์ ฉันไม่คิดว่าคุณจะทำอะไรหลุดและแน่นอนฉันคิดว่ามันสื่อความหมายได้ดีกว่าเมื่อสิ่งที่คุณมีคือระดับคุณค่า
Tom Quarendon

16
ไม่จำเป็นต้องจบคลาสใน java ด้วยอัฒภาค
เชฟฟาโรห์

14
แก้ไขฉันถ้าฉันผิด แต่ประเด็นของโครงสร้างคือมันถูกส่งผ่านโดยค่าที่ไม่ได้อ้างอิง ชั้นเรียนจะผ่านการอ้างอิงเสมอ นั่นเป็นเหตุผลที่คำตอบนี้ผิด
ULazdins

4
@ULazdins: ฉันคิดว่าคุณกำลังสับสนโครงสร้าง C # กับโครงสร้าง C ++ เมื่อคุณส่งคลาสไปยังเมธอดใน C ++ จะเรียกตัวสร้างการคัดลอกซึ่งโดยค่าเริ่มต้นจะคัดลอกแต่ละฟิลด์ คุณต้องใช้ไวยากรณ์อย่างชัดเจนเพื่อส่งต่อโดยการอ้างอิง
Ronaldo Nazarea

4
@PabloAriel ฉันไม่เห็นด้วยกับความคิดเห็นก่อนหน้านี้ของฉัน ความคิดของฉันได้รับอนุญาตให้พัฒนาไปกว่า 7 ปี;)
Michael Berry

16

จริงๆแล้วโครงสร้างใน C ++ เป็นคลาส (เช่นคุณสามารถกำหนดเมธอดได้ที่นั่นมันสามารถขยายได้มันทำงานเหมือนกับคลาสทุกประการ) ข้อแตกต่างเพียงอย่างเดียวคือตัวดัดแปลงการเข้าถึงเริ่มต้นถูกตั้งค่าเป็นสาธารณะ (สำหรับคลาสที่ตั้งค่าเป็นส่วนตัว โดยค่าเริ่มต้น).

นี่เป็นข้อแตกต่างเพียงอย่างเดียวของ C ++ หลายคนไม่รู้ว่า ; )


14

Java ไม่มีโครงสร้างของอะนาล็อกกับ C ++ แต่คุณสามารถใช้คลาสกับสมาชิกสาธารณะทั้งหมดได้


15
จริงๆแล้วstructใน C ++ นั้น ( ค่อนข้างมาก ) เหมือนกับclassใน C ++
Joachim Sauer

ทำไมสมาชิกเหล่านี้ถึงต้องเป็นpublicทำไมไม่เพียงแค่ให้พวกเขาอยู่ภายในแพ็คเกจอย่างน้อยที่สุด? โดยทั่วไปคลาสแบบนั้นไม่เหมาะสำหรับใช้ใน API (หากเป็นเพียงการnullอ้างอิงที่เป็นไปได้) ใช้การมองเห็นขั้นต่ำเสมอ!
Maarten Bodewes

8

ด้วย Project JUnion คุณสามารถใช้โครงสร้างใน Java โดยใส่คำอธิบายประกอบคลาสด้วยคำอธิบายประกอบ @Struct

@Struct
class Member {
  string FirstName; 
  string LastName;  
  int BirthYear; 
}

ข้อมูลเพิ่มเติมที่เว็บไซต์ของโครงการ: https://tehleo.github.io/junion/


สิ่งที่ดี. ตอนนี้ฉันเข้าใจแล้วว่าโครงสร้าง (วัตถุ) แสดงในหน่วยความจำอย่างไร ขอบคุณมาก :)
user218046


6

ใช่ Java ยังไม่มีประเภทโครงสร้าง / ค่า แต่ใน Java เวอร์ชันที่กำลังจะมาถึงเราจะได้รับinline classซึ่งคล้ายกับ struct ใน C # และจะช่วยให้เราเขียนโค้ดที่จัดสรรได้ฟรี


inline class point { 
  int x;
  int y;
}


6

Java 14 ได้เพิ่มการรองรับสำหรับ Records ซึ่งเป็นชนิดข้อมูลที่มีโครงสร้างซึ่งสร้างได้ง่ายมาก

คุณสามารถประกาศบันทึก Java ได้ดังนี้:

public record AuditInfo(
    LocalDateTime createdOn,
    String createdBy,
    LocalDateTime updatedOn,
    String updatedBy
) {}
 
public record PostInfo(
    Long id,
    String title,
    AuditInfo auditInfo
) {}

และคอมไพเลอร์ Java จะสร้างคลาส Java ต่อไปนี้ที่เชื่อมโยงกับAuditInfoRecord:

public final class PostInfo
        extends java.lang.Record {
    private final java.lang.Long id;
    private final java.lang.String title;
    private final AuditInfo auditInfo;
 
    public PostInfo(
            java.lang.Long id,
            java.lang.String title,
            AuditInfo auditInfo) {
        /* compiled code */
    }
 
    public java.lang.String toString() { /* compiled code */ }
 
    public final int hashCode() { /* compiled code */ }
 
    public final boolean equals(java.lang.Object o) { /* compiled code */ }
 
    public java.lang.Long id() { /* compiled code */ }
 
    public java.lang.String title() { /* compiled code */ }
 
    public AuditInfo auditInfo() { /* compiled code */ }
}
 
public final class AuditInfo
        extends java.lang.Record {
    private final java.time.LocalDateTime createdOn;
    private final java.lang.String createdBy;
    private final java.time.LocalDateTime updatedOn;
    private final java.lang.String updatedBy;
 
    public AuditInfo(
            java.time.LocalDateTime createdOn,
            java.lang.String createdBy,
            java.time.LocalDateTime updatedOn,
            java.lang.String updatedBy) {
        /* compiled code */
    }
 
    public java.lang.String toString() { /* compiled code */ }
 
    public final int hashCode() { /* compiled code */ }
 
    public final boolean equals(java.lang.Object o) { /* compiled code */ }
 
    public java.time.LocalDateTime createdOn() { /* compiled code */ }
 
    public java.lang.String createdBy() { /* compiled code */ }
 
    public java.time.LocalDateTime updatedOn() { /* compiled code */ }
 
    public java.lang.String updatedBy() { /* compiled code */ }
}

ขอให้สังเกตว่าตัวสร้างวิธีการเข้าถึงเช่นเดียวกับequals, hashCodeและtoStringถูกสร้างขึ้นสำหรับคุณดังนั้นมันสะดวกมากที่จะใช้ Java ประวัติ

Java Record สามารถสร้างได้เหมือนกับออบเจ็กต์ Java อื่น ๆ :

PostInfo postInfo = new PostInfo(
    1L,
    "High-Performance Java Persistence",
    new AuditInfo(
        LocalDateTime.of(2016, 11, 2, 12, 0, 0),
        "Vlad Mihalcea",
        LocalDateTime.now(),
        "Vlad Mihalcea"
    )
);

สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับวิธีการที่คุณสามารถปรับแต่ง Java ประวัติตรวจสอบบทความนี้


2

โครงสร้างที่ "บริสุทธิ์" ไม่รองรับใน Java เช่น C # รองรับstructคำจำกัดความที่แสดงถึงค่าและสามารถจัดสรรได้ตลอดเวลา

ใน Java วิธีที่ไม่เหมือนใครในการหาค่าประมาณของโครงสร้าง C ++

struct Token
{
    TokenType type;
    Stringp stringValue;
    double mathValue;
}

// Instantiation

{
    Token t = new Token;
}

โดยไม่ต้องใช้ (บัฟเฟอร์แบบคงที่หรือรายการ) กำลังทำสิ่งที่ชอบ

var type = /* TokenType */ ;
var stringValue = /* String */ ;
var mathValue = /* double */ ;

ดังนั้นเพียงแค่จัดสรรตัวแปรหรือกำหนดแบบคงที่ในคลาส


0

พร้อมกับ Java 14 มันเริ่มรองรับ Record คุณอาจต้องการตรวจสอบว่าhttps://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/lang/Record.html

และมี Sealed Classes หลัง Java 15 https://openjdk.java.net/jeps/360


มีวิธีใดบ้างที่คุณสามารถยกตัวอย่างบันทึกได้
Scratte

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