Ale*_*lex 4 java coldfusion arraylist lucee
编辑:错误已提交。
假设我有两个相互指向的 ArrayLists(循环引用):
x = createObject("java", "java.util.ArrayList").init();
y = createObject("java", "java.util.ArrayList").init();
x.add(y);
y.add(x);
Run Code Online (Sandbox Code Playgroud)
如果我调用hashCode
它们中的任何一个,它会导致StackOverflowError
ArrayList 实现。这是可以预料的。
但是,当我调用 时System.identityHashCode
,是不是应该使用Object.hashCode
实现,它不会跟随 ArrayList 中的元素,因此不会导致StackOverflowError
?
为给定对象返回与默认方法 hashCode() 返回的哈希码相同的哈希码,无论给定对象的类是否覆盖 hashCode()。
在 Adobe ColdFusion 中,此代码工作正常:
System = createObject("java", "java.lang.System");
System.identityHashCode(x); // returns some integer
System.identityHashCode(y); // returns another integer
Run Code Online (Sandbox Code Playgroud)
(这显然也适用于本机编译并使用 Java 运行。)
然而,在 Lucee 中,它会立即导致StackOverflowError
:
lucee.runtime.exp.NativeException: java.lang.StackOverflowError
at java.base/java.util.ArrayList.hashCodeRange(ArrayList.java:627)
at java.base/java.util.ArrayList.hashCode(ArrayList.java:614)
at java.base/java.util.ArrayList.hashCodeRange(ArrayList.java:627)
at java.base/java.util.ArrayList.hashCode(ArrayList.java:614)
[...]
Run Code Online (Sandbox Code Playgroud)
为什么它在hashCode
这里运行 ArrayList 实现?
两个 CFML 引擎都在同一个 servlet (Tomcat 9) 上使用相同的 JVM (HotSpot) 和 Java 版本 (11) 运行。我想了解为什么他们的行为不同。
System.identityHashCode
is的实现native
- 它是在 VM 级别实现的;这不是java代码。iHC 的规范故意含糊不清。
它含糊不清的原因是因为它高度依赖于平台,并且规范试图为异国平台上的 VM 实现者提供足够的余地(ColdFusion 和 Lucee 肯定算数,不是吗?)以制作符合规范的 impl。
从技术上讲,hashCode implObject
可以扫描字段,尽管这会非常低效(因为 System.iHC 在需要快速响应的地方被大量使用,而且绝非如此),而且您不是只有一个假设 System.iHC 即使在(最终)引用自身的对象中也不会永远循环。
但是,关键是,这些都是广泛使用的假设;该方法的规范中没有任何内容实际上说它是这样工作的。
另一方面,lucee 所采取的回旋余地(如果你说的是真的),是相当过分的。
因此,您现在被困住了。这些都是真的:
但先给他们一个机会,在你认为他们会打开门之前,嗯!不是我们的错!他们在这里在技术上可用的路线。
如果他们拒绝了您的错误报告,和/或您想在将其提交到他们的错误跟踪器之前对其进行改进,那么您可能希望调查以下一些事项:
==
在 lucee中表现如何?是否new String("foo") == new String("foo")
等于真?但最重要的是对露西人保持一些耐心。由于他们所使用的平台的限制,他们完全有可能没有真正实现 System.iHC 的真正方法,在这种情况下,他们只能表示同情和耸耸肩。
归档时间: |
|
查看次数: |
57 次 |
最近记录: |