我想传递不可变 Java 对象作为引用,是否有替代 AtomicReferences 或 Array 或 List 的方法?
I want to pass immutable Java objects as a reference, is there an alternative to AtomicReferences or Array or List?
假设我想要一个方法来修改 2 个字符串(或任何其他不可变 class),我不能 return 单个对象。所以我可以传递一个 List、String[] 或 2 个 AtomicReference 对象。这些都有缺点。列表和数组不允许为每个参数命名,我们依靠元素的顺序来确保设置正确的字符串。 AtomicReference 旨在进行原子更新,因此它所做的远远超过我需要它做的。我只需要这样的东西:
public class Reference <T> {
private T value;
public T get() {
return value;
}
public void set(T value) {
this.value = value;
}
}
我认为像这样的 class 在某些 Apache 库或 Spring 库中可用,但我找不到这样的东西。我认为这对许多开发人员来说是一个非常基本的需求,所以它在我不知道的某些第 3 方库中吗?
这主要适用于 2 或 3 个对象的情况。当有 >3 个不可变对象时,我可能会创建一个新的 class 来保存这些引用。
我也知道 Apache Pair 和 Triple,但它们与 List 有同样的问题,我无法在其中命名参数。
如果您希望“命名元组”不可变,最适合您要求的是 Java 14+ record
class。本质上,它是一个轻量级的 class,大致类似于 C / C++ struct
....但不可变;
当你需要可变的“命名元组”时(或者如果Java 14+还不是你的选择),有两种选择:
如果“字段”名称是动态的,那么您可以使用 Map
。任何 Map
实现都可以。这有问题:
- 您必须使用
m.get(name)
和 m.put(name, value)
语法。
- 编译器无法检查您使用的
name
字符串是否正确。
- 所有值都必须是同一类型,或者具有相同的基类型。如果“字段”有不同的类型,则需要使用类型转换;例如从
Object
到预期类型。
如果“字段”名称是静态的(即您希望能够将它们称为 Java 标识符,唯一的选择是声明一个常规的 class . 它可以是一个“未封装的”class;例如
public class Things {
public Type1 thing1;
public Type2 thing2;
}
字段可以声明为 final
然后你需要
声明一个构造函数。
虽然拥有 getter、setter 和构造函数是一种很好的风格,但 Java 语言不会强制您声明 and/or 使用它们。您只需要了解忽略封装的后果。 (并且能够应对负面代码审查...)
无论如何,您不能设计一个库class,其中您的字段名称是常规参数或类型参数。 (或者至少,不是以常规 Java 代码可以 使用 的方式;例如使用 x.name
或 x.getName()
。)这就是为什么你找不到!
假设我想要一个方法来修改 2 个字符串(或任何其他不可变 class),我不能 return 单个对象。所以我可以传递一个 List、String[] 或 2 个 AtomicReference 对象。这些都有缺点。列表和数组不允许为每个参数命名,我们依靠元素的顺序来确保设置正确的字符串。 AtomicReference 旨在进行原子更新,因此它所做的远远超过我需要它做的。我只需要这样的东西:
public class Reference <T> {
private T value;
public T get() {
return value;
}
public void set(T value) {
this.value = value;
}
}
我认为像这样的 class 在某些 Apache 库或 Spring 库中可用,但我找不到这样的东西。我认为这对许多开发人员来说是一个非常基本的需求,所以它在我不知道的某些第 3 方库中吗?
这主要适用于 2 或 3 个对象的情况。当有 >3 个不可变对象时,我可能会创建一个新的 class 来保存这些引用。
我也知道 Apache Pair 和 Triple,但它们与 List 有同样的问题,我无法在其中命名参数。
如果您希望“命名元组”不可变,最适合您要求的是 Java 14+ record
class。本质上,它是一个轻量级的 class,大致类似于 C / C++ struct
....但不可变;
当你需要可变的“命名元组”时(或者如果Java 14+还不是你的选择),有两种选择:
如果“字段”名称是动态的,那么您可以使用
Map
。任何Map
实现都可以。这有问题:- 您必须使用
m.get(name)
和m.put(name, value)
语法。 - 编译器无法检查您使用的
name
字符串是否正确。 - 所有值都必须是同一类型,或者具有相同的基类型。如果“字段”有不同的类型,则需要使用类型转换;例如从
Object
到预期类型。
- 您必须使用
如果“字段”名称是静态的(即您希望能够将它们称为 Java 标识符,唯一的选择是声明一个常规的 class . 它可以是一个“未封装的”class;例如
public class Things { public Type1 thing1; public Type2 thing2; }
字段可以声明为
final
然后你需要 声明一个构造函数。虽然拥有 getter、setter 和构造函数是一种很好的风格,但 Java 语言不会强制您声明 and/or 使用它们。您只需要了解忽略封装的后果。 (并且能够应对负面代码审查...)
无论如何,您不能设计一个库class,其中您的字段名称是常规参数或类型参数。 (或者至少,不是以常规 Java 代码可以 使用 的方式;例如使用 x.name
或 x.getName()
。)这就是为什么你找不到!