On Oct 27, 2020, at 12:27 PM, Dan Smith <daniel.sm...@oracle.com> wrote: > > This tooling will support common bytecode patterns like 'new Foo; dup; ...; > invokespecial Foo.<init>;', but will not be a comprehensive solution. > (Mimicking the behavior of instance initialization method invocation in full > generality would be a very difficult task.)
One of the reasons it’s not going to be comprehensive is code like new Integer(complicatedExpr()), in which the `new` and `invokespecial <init>` are separated by (almost) arbitrarily complex bytecode. The two instructions don’t even have to be in the same basic block (at the bytecode level): new Integer(foo() ? bar() : baz()) // compiles to 4 BB’s in a diamond If we add switch expressions with large sub-blocks, I think we get peak separation of the start and end parts of the new/init dance: new Integer(switch (x) { case 1 -> { complicatedBlock: try { … } catch ... ; return 0; default -> { for (;;) … }} ) All of this gives me yet one more reason we would have been better off with factory methods instead of open-coding the new/init dance. It was, in hindsight, a false economy to open code the object creation “guts” instead of putting them in factory API points. And with an eye toward future evolutions of legacy code (legacy code not yet in existence!), and uniformity with the factory methods of inline classes, let’s try harder to get rid of the new/init dance for identity objects. — John