O Java oferece suporte a structs?

95

O Java tem um análogo de um C ++ struct:

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

Eu preciso usar meu próprio tipo de dados.

Dmitry
fonte
Para aqueles que copiam muito literalmente: os campos em Java realmente precisam começar com um caractere minúsculo, portanto firstName, lastNamee birthYear(ou é yearOfBirthclaro).
Maarten Bodewes

Respostas:

52

Java definitivamente não tem structs :) Mas o que você descreve aqui parece um tipo de classe JavaBean.

Heiko Rupp
fonte
31
Bem, uma classe com apenas variáveis ​​públicas se parece muito com um stuct.
mglauche
10
Teremos registros 9 anos após esta resposta, em Java 14. É engraçado como o tempo voa.
George Leung
2
Uma das principais diferenças entre classes e estruturas é como elas se comportam na memória. A esse respeito, essa resposta está errada. Java não tem nada que se comporte como uma estrutura, mas espero que inline classem algum momento no futuro próximo o que eu acredito seja mais como uma estrutura.
Will Calderwood
Um bean tem propriedades (ou seja, getters e geralmente setters) e atualmente é comumente anotado para estar de acordo com os requisitos de um bean.
Maarten Bodewes
89

O equivalente em Java a uma estrutura seria

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

e não há nada de errado com isso nas circunstâncias certas. Quase o mesmo que em C ++ realmente em termos de quando você usa struct verses quando você usa uma classe com dados encapsulados.

Tom Quarendon
fonte
22
Eu usaria classes do tipo "POD" em java nas mesmas circunstâncias que faço em C ++. "Objetos de valor" vêm à mente no J2EE, onde você tem um método que está retornando vários valores de uma vez. Não adianta encapsular os dados com os métodos getter e setter, apenas torne os campos públicos - mais curtos e descritivos. Qualquer coisa "adequada" eu tendo a encapsular, da mesma forma que faço em C ++. Portanto, mantenho meu comentário original, mas é uma escolha de estilo. Não acho que você perca nada, e na verdade acho que é mais descritivo quando o que você tem é uma classe de valor.
Tom Quarendon,
16
Não há necessidade de terminar uma classe em java com ponto e vírgula.
Chef Faraó
15
Corrija-me se eu estiver errado, mas o ponto do Struct é que ele é passado por valor e não por referência. As aulas sempre são passadas por referência. É por isso que essa resposta está errada.
ULazdins
5
@ULazdins: Acho que você está confundindo estruturas C # com estruturas C ++. Quando você passa uma classe para um método em C ++, ele chama o construtor de cópia, que por padrão copia cada campo. Você deve usar explicitamente a sintaxe para passá-lo por referência.
Ronaldo Nazarea
5
@PabloAriel Eu também discordo do meu comentário anterior. Meu pensamento pode evoluir ao longo de 7 anos;)
Michael Berry
16

Na verdade, um struct em C ++ é uma classe (por exemplo, você pode definir métodos lá, pode ser estendido, funciona exatamente como uma classe), a única diferença é que os modfiers de acesso padrão são definidos como públicos (para classes eles são definidos como privados por padrão).

Esta é realmente a única diferença em C ++, muitas pessoas não sabem disso. ; )

Damian Wojakowski
fonte
15

Java não tem um análogo aos structs do C ++, mas você pode usar classes com todos os membros públicos.

Eugene Burtsev
fonte
15
Na verdade, a structem C ++ é ( praticamente ) a mesma coisa que a classem C ++.
Joachim Sauer
@JoachimSauer Weird! Isso me faz pensar em como as classes C ++ são diferentes das estruturas C.
jpaugh
@MaartenBodewes O problema com internalé que é menos visível do que protected. Um internalmembro declarado em com.myapp.libnão estará acessível em com.myapp.main, portanto, você não poderá acessá-lo em qualquer lugar no mesmo projeto.
jpaugh
@jpaugh: Não sou especialista em C ou C ++, foi apenas um trivia interessante e aleatório que aprendi. Mas acho que, como as classes C ++ são quase iguais às estruturas C ++, acho que ambas são bastante diferentes das estruturas C (que não suportam diretamente a herança de construtores / métodos associados).
Joachim Sauer
@jpaugh Todo o motivo pelo qual mencionei o problema publicé que você pode não querer expor um registro que pode facilmente ser colocado em um estado errado para muitas classes; deve ser mantido preferencialmente interno. Observe que os registros Java, conforme mencionado nesta resposta, são imutáveis ​​(mas você sempre pode usar um método de fábrica para criar novos registros, é claro)
Maarten Bodewes
10

Java 14 adicionou suporte para registros, que são tipos de dados estruturados muito fáceis de construir.

Você pode declarar um registro Java assim:

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

E, o compilador Java irá gerar a seguinte classe Java associada ao AuditInfoRegistro:

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 */ }
}

Observe que o construtor, os métodos de acesso, bem como equals, hashCodee toStringsão criados para você, portanto, é muito conveniente usar Registros Java.

Um registro Java pode ser criado como qualquer outro objeto 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"
    )
);

Para obter mais detalhes sobre como personalizar registros Java, consulte este artigo .

Vlad Mihalcea
fonte
8

Com o Project JUnion, você pode usar structs em Java anotando uma classe com a anotação @Struct

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

Mais informações no site do projeto: https://tehleo.github.io/junion/

Leo
fonte
Coisa boa. Agora entendo como as estruturas (objetos) são representadas na memória. Obrigado cara :)
user218046
7

Sim, o Java ainda não tem tipo de estrutura / valor. Mas, na próxima versão do Java, vamos obter algo inline classsemelhante a struct em C # e nos ajudará a escrever código livre de alocação.


inline class point { 
  int x;
  int y;
}

ganesan arunachalam
fonte
quem votou contra isso, posso saber por quê? Você pode ler mais sobre a classe java inline aqui infoq.com/articles/inline-classes-java
ganesan arunachalam
6

Sim, uma aula é o que você precisa. Uma classe define um tipo próprio.

Markus
fonte
2

Structs "realmente" puros não são suportados em Java. Por exemplo, C # oferece suporte a structdefinições que representam valores e podem ser alocados a qualquer momento.

Em Java, a maneira única de obter uma aproximação de estruturas C ++

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

// Instantiation

{
    Token t = new Token;
}

sem usar um (buffer estático ou lista) está fazendo algo como

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

Portanto, basta alocar variáveis ​​ou defini-las estaticamente em uma classe.

Divã
fonte
Java não suporta var, não é?
jpaugh
0

Junto com Java 14, ele começa a oferecer suporte a Record. Você pode querer verificar se https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/lang/Record.html

public record Person (String name, String address) {}

Person person = new Person("Esteban", "Stormhaven, Tamriel");

E há classes seladas após o Java 15. https://openjdk.java.net/jeps/360

sealed interface Shape permits Circle, Rectangle {

  record Circle(Point center, int radius) implements Shape { }

  record Rectangle(Point lowerLeft, Point upperRight) implements Shape { } 
}
Orcun
fonte
Existe alguma maneira de dar um exemplo de registro?
Scratte
Por favor, não poste apenas alguma ferramenta ou biblioteca como resposta. Demonstre pelo menos como resolve o problema na própria resposta.
Yatin
Desculpe, acabei de receber a notificação. Pensei que fosse simples, mas você está certo. Adicionados alguns exemplos.
Orcun