Java는 구조체를 지원합니까?


95

합니까 자바는 C ++의 아날로그 있습니다 struct:

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

내 데이터 유형을 사용해야합니다.


너무 문자 그대로 복사하는 사람들을 위해 : Java의 필드는 실제로 소문자로 시작해야하므로 firstName, lastName및 birthYear(또는 yearOfBirth물론).
— Maarten Bodewes

답변:


51

Java에는 확실히 구조체가 없습니다. :) 그러나 여기에서 설명하는 것은 JavaBean 종류의 클래스처럼 보입니다.


31
음, 공개 변수 만있는 클래스는 스터 트처럼 보입니다.
— mglauche 2011 년

10
우리는 이 답변 이후 9 년 후에 Java 14에 기록 을 갖게 될 것 입니다. 시간이 얼마나 빨리 가는지 재밌습니다.
— George Leung

클래스와 구조체의 주요 차이점 중 하나는 메모리에서 작동하는 방식입니다. 이 점에서이 대답은 잘못되었습니다. Java에는 구조체처럼 작동하는 것이 없지만 inline class가까운 장래에 내가 구조체와 더 비슷하다고 생각하는 시점 이 있기를 바랍니다 .
— Will Calderwood

빈에는 속성 (즉, getter 및 일반적으로 setter)이 있으며 요즘에는 일반적으로 빈에 대한 요구 사항을 준수하도록 주석이 추가됩니다.
— Maarten Bodewes

88

Java에서 구조체에 해당하는 것은 다음과 같습니다.

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

그리고 올바른 상황에서는 잘못된 것이 없습니다. 캡슐화 된 데이터가있는 클래스를 사용할 때 구조체 구절을 언제 사용 하는가 측면에서 C ++에서와 거의 동일합니다.


22
C ++에서와 동일한 환경에서 Java에서 "POD"유형 클래스를 사용합니다. 한 번에 여러 값을 반환하는 메서드가있는 J2EE에서는 "값 개체"가 떠 오릅니다. getter 및 setter 메서드로 데이터를 캡슐화 할 필요가 없습니다. 필드를 더 짧고 더 설명 적으로 공개하기 만하면됩니다. 내가 캡슐화하는 "적절한"모든 것은 C ++에서하는 것과 동일합니다. 그래서 나는 내 원래 의견을지지하지만 스타일 선택입니다. 나는 당신이 어떤 것도 잃어버린 것이라고 생각하지 않으며 실제로 당신이 가진 것이 가치 등급 일 때 더 설명 적이라고 생각합니다.
— Tom Quarendon 2011 년

16
세미콜론으로 Java에서 클래스를 종료 할 필요가 없습니다.
— Chef Pharaoh

14
내가 틀렸다면 정정하십시오.하지만 Struct의 요점은 참조가 아닌 값으로 전달된다는 것입니다. 클래스는 항상 참조로 전달됩니다. 이것이이 대답이 잘못된 이유입니다.
— ULazdins

4
@ULazdins : C # 구조체와 C ++ 구조체를 혼동하고 있다고 생각합니다. 클래스를 C ++의 메서드에 전달할 때 기본적으로 각 필드를 복사하는 복사 생성자를 호출합니다. 참조로 전달하려면 구문을 명시 적으로 사용해야합니다.
— 호나우두 Nazarea

4
@PabloAriel 나는 또한 내 이전 의견에 동의하지 않습니다. 내 생각은 7 년에 걸쳐 진화 할 수 있습니다.)
— Michael Berry

17

실제로 C ++의 구조체는 클래스입니다 (예 : 여기에서 메서드를 정의 할 수 있고 확장 할 수 있으며 클래스와 똑같이 작동 함). 유일한 차이점은 기본 액세스 수정자가 public으로 설정되어 있다는 것입니다 (클래스의 경우 private로 설정 됨). 기본적으로).

이것은 실제로 C ++의 유일한 차이점이며 많은 사람들이 그것을 모릅니다. ; )


14

Java는 C ++의 구조체와 유사하지 않지만 모든 공용 멤버와 함께 클래스를 사용할 수 있습니다.


15
실제로 structC ++의 a 는 C ++의 a 와 거의 같습니다 class.
— Joachim Sauer

이러한 멤버가이어야하는 이유는 무엇 public입니까? 최소한 패키지 내부에 있어야하는 이유는 무엇입니까? 이와 같은 클래스는 일반적으로 API에서 사용하기에 적합하지 않습니다 (가능한 null참조 용인 경우). 항상 최소한의 가시성을 사용하십시오!
— Maarten Bodewes

8

Project JUnion을 사용하면 @Struct 주석으로 클래스에 주석을 달아 Java에서 구조체를 사용할 수 있습니다.

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

프로젝트 웹 사이트에서 더 많은 정보 : https://tehleo.github.io/junion/


좋은 물건. 이제 구조 (객체)가 메모리에서 어떻게 표현되는지 이해합니다. 감사합니다 :)
— user218046

7

Java 14에는 빌드하기 매우 쉬운 구조화 된 데이터 유형 인 레코드에 대한 지원이 추가되었습니다.

다음과 같이 Java 레코드를 선언 할 수 있습니다.

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

그리고 Java 컴파일러는 AuditInfo레코드 와 연관된 다음 Java 클래스를 생성합니다 .

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 객체처럼 생성 할 수 있습니다.

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 레코드를 사용자 정의하는 방법에 대한 자세한 내용은 이 기사를 확인 하십시오 .


6

네, 수업이 필요합니다. 클래스는 고유 한 유형을 정의합니다.


6

예, Java에는 아직 구조체 / 값 유형이 없습니다. 그러나 차기 버전의 Java에서는 inline classC #의 struct와 유사한 것을 얻고 할당 무료 코드를 작성하는 데 도움이 될 것입니다.


inline class point { 
  int x;
  int y;
}


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 을 확인하는 것이 좋습니다.

그리고 Java 15 이후에는 Sealed Class가 있습니다. https://openjdk.java.net/jeps/360


기록의 예를 제시 할 수있는 방법이 있습니까?
— Scratte

답변으로 도구 나 라이브러리를 게시하지 마십시오. 최소한 답변 자체에서 문제 를 해결하는 방법을 보여 줍니다 .
— Yatin
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.