32

我已经开始阅读有关Project Valhalla的内容,但有些东西我真的不明白,它是Value Types.

这是我的理解:

1)不能作为参考比较的对象吗?

final ValueType a = new ValueType();
final ValueType b = a;
System.out.println(a==b); returns false????

Google AutoValue 代码示例中,它声明

if(o == this){return true;}//equals method implementation what is this? I am comparing references here right?

2)根据维基百科,没有继承的高效小“对象”。是什么Small Objects?意思Without inheritance

这不能使用VT吗?

public final class ValueType extends Any //is this not possible??

3) 为什么使用它们?将使用哪种方案以及如何使用。

4) 根据Google AutoValue Library,简而言之,值类型对象是没有标识的对象,即如果两个值对象各自的内部状态相等,则认为它们相等。我的问题是:他们是否有状态,是否应该实施equalshashcode. 没有身份的对象是什么意思?

5)这个断言正确吗?

public static void main(final String[] args)
{
    final Test clazz = new Test();
    final AutoValue value = new AutoValue("Java Belongs to SUN");//Constructor Name
    clazz.mutate(value);
    System.out.println(value.getName()); //would print: Java Belongs to SUN??
}
private void mutate(final AutoValue value){value.setName("Java now is part of Oracle Corporation");return;}

如果是这样,JVM 会获得内存而不是Objects or Values在方法调用之间跟踪它吗?

Project Valhalla是 Java 10 初始项目的一部分,将于 2018 年左右准备就绪。

4

4 回答 4

18

你最后的断言是正确的。将ValueType变量作为参数传递给函数时,它们会被完全复制,而不是通常只是获取对对象的引用的副本。这使您可以将小对象视为 int 或 boolean 之类的值类型。

于 2015-04-12T16:53:30.987 回答
15

1) 在 Project Valhalla 下,两个 ValueType 将直接按字段进行比较,即使是 == 检查,也很像原始类型。使用 Google 的 AutoValue 类型,您永远不会直接使用 ==,因为这仍然是身份检查。

2)小对象意味着这应该用于只有几个字段的对象,因为对象的全部内容将被重复复制。大对象最好通过引用传递。

没有继承意味着您将无法对值类型对象使用多态性。因为值类型旨在直接存储,就像原始值一样,它们不包含任何类信息,因此 JVM 必须始终能够从程序本身推断对象是什么,而不是从对象的任何信息中推断出来。例如,整数字段可以是值类型成员,而数字字段必须仍然是引用。

3) 它们用于避免访问对象成员通常需要的取消引用惩罚。例如,对于一个点列表,每个点实际上是对内存中 x 和 y 值的引用,因此对列表进行迭代将涉及许多取消引用。如果点直接存储在列表中,则可以避免这种情况。

4)没有身份的对象意味着关于对象的所有重要的是它的价值。正如一个 int 值 1 应该与所有其他 int 值 1 相同,并且所有字符串“hello world”都等于所有其他字符串“hello world”,无论它们实际上是否是同一个对象。相比之下,两个同时为空但时间相等的 ArrayList 具有标识,因为它们是可变的,并且将元素添加到一个列表必须不同于将元素添加到另一个列表。

5) 在 Valhalla 项目下,如果 AutoValue 是一个值对象,它将是不可变的,因此不会调用 setName 方法。这类似于您永远无法将 1 变为 2,而是修改 1 的位置,以便 2 代替。

来源:http ://cr.openjdk.java.net/~jrose/values/values-0.html

于 2015-09-19T02:43:16.690 回答
1

其他答案很好,但是关于对象的核心点还有另一种观点:它们为您提供堆栈语义。

含义:在 Valhalla 项目之前,您要么拥有原始“对象”, 要么拥有参考对象。第一个可以存在于堆栈上,但真正的对象只存在于堆上。

值对象将改变这一点。您可以拥有“真实”对象——但它们的数据驻留在堆栈中。这意味着您没有任何引用(因此取消引用的成本) - 就像原始类型一样,直接放在堆栈上。但是现在该值可以不仅仅是一个单一的 int、long、...... - 你可以拥有一个真正的“复杂”对象 - 但它的所有数据都直接存在于堆栈中。

正因为如此,你a == b现在可以做得很好——因为现在你不再比较指向堆的引用——而是a直接b拥有它们对应的值。

于 2018-02-04T18:34:18.473 回答
1

更新 2019/2020,构建 14-valhalla+4-55 (2019/8/30)

内联类是“值类型”的新名称。根据当前项目状态,内联类不支持继承,但能够扩展接口。以下声明是合法的:

public inline class MyInlineClass extends SomeJavaInterface {}

他们确实有equals, hashcode(and toString) 方法。"==" 操作和equals(默认实现)对于简单情况是相同的,其中仅涉及内联类和原始字段。但一般情况下并非如此。

如果您将经典的 Java 对象(包括字符串和数组)添加为内联类中的字段,它会变得混乱。在这种情况下,“==”操作很可能不再按预期工作,您必须回退到经典的自定义equal实现。

内联对象是不可变的,不支持克隆(克隆没有意义)。


内联类的一个可能用例是复数或矩阵代数,这对于人工智能系统的神经网络算法至关重要。

于 2020-03-22T07:22:20.980 回答