Java有类似于C++ struct
的替代品吗?
struct Member {
string FirstName;
string LastName;
int BirthYear;
};
我需要使用自己的数据类型。
Java有类似于C++ struct
的替代品吗?
struct Member {
string FirstName;
string LastName;
int BirthYear;
};
我需要使用自己的数据类型。
在Java中与结构体相当的是
class Member
{
public String firstName;
public String lastName;
public int birthYear;
};
在适当的情况下做这样的事情是没有问题的。实际上,这与在C++中何时使用结构体以及何时使用封装数据的类非常相似。
Java 绝对没有结构体:) 但您在此描述的看起来像是 JavaBean 类。
Java 14增加了Records的支持,它是一种非常容易构建的结构化数据类型。
您可以像这样声明Java记录:
record Person(String name, int age) { }
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 Records非常方便。
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"
)
);
实际上在C++中,结构体就是一个类(例如您可以在其中定义方法,它可以被扩展,它的工作方式与类完全相同),唯一的区别是默认访问修饰符被设置为public(对于类,默认情况下设置为private)。
这真的是C++中唯一的区别,很多人不知道。;)
不,Java目前还没有结构体/值类型。但是,在即将发布的Java版本中,我们将获得inline class
,它类似于C#中的struct,有助于我们编写无需分配内存的代码。
inline class point {
int x;
int y;
}
ref
关键字,C#将所有内容(包括引用)都按值传递。你的意思是结构体对象的内容被作为值传递(与C类似)。是的,自从我最初提出问题以来,我已经深入研究了Valhalla:JVM确实被修改以允许在堆栈上使用复合值类型。JUnion项目似乎是一个奇怪的半成品,我还没有深入研究过。 - alifeJava没有类似于C++的结构体,但您可以使用全部为公共成员的类。
struct
和class
基本上是一样的东西(参见http://en.wikipedia.org/wiki/C%2B%2B_classes#Differences_between_struct_and_classes_in_C.2B.2B)。 - Joachim Sauerpublic
的问题的原因是您可能不想将一个容易被放入错误状态的记录暴露给许多类; 最好将其保持为内部。请注意,正如此答案中所述,Java记录是不可变的(但您当然可以使用工厂方法来创建新记录)。 - Maarten Bodewes通过在类上注释@Struct注释,您可以在Java中使用结构体(Project JUnion)
@Struct
class Member {
string FirstName;
string LastName;
int BirthYear;
}
有关该项目的更多信息,请访问其网站:https://tehleo.github.io/junion/
是的,你需要一个类。一个类定义了自己的类型。
随着Java 14的发布,它开始支持Record。您可以查看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");
sealed interface Shape permits Circle, Rectangle {
record Circle(Point center, int radius) implements Shape { }
record Rectangle(Point lowerLeft, Point upperRight) implements Shape { }
}
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 */ ;
var
,是吗? - jpaughvar
只是让编译器在编译时推断类型,在运行时没有区别。 - MC Emperorvar
并不能创建复合值类型,这也是结构体的关键所在。此外,将它们放入类中有什么作用呢?你是在回答他需要自己的类型,还是在回答结构体的何时/为什么/如何使用?如果是后者,那么这个回答就没有意义了。 - alife
firstName
、lastName
和birthYear
(或者当然也可以使用yearOfBirth
)。 - Maarten Bodewes