Continuing from my Adventures in translating Java to Delphi.NET: Part 1 article...
In translating Java to Delphi.NET, one of the weirder things I came across is the following...
{$AUTOBOX ON}uses java.util;...var HM: Hashmap; Obj1: TObject; Obj2: string; S: string;begin HM := Hashmap.Create; S := '1'; HM.put('5', '1'); HM.put(6, S); Obj1 := HM.get('5'); WriteLn(Obj1 as string); // Specified cast is not valid. Obj2 := HM.get(6) as string; WriteLn(Obj1); // Got compiled as TextOutput.Output.WriteWideString(Obj1.ToString(), 0).WriteLn(); WriteLn(Obj2); // Got compiled as TextOutput.Output.WriteWideString(Obj2.ToString(), 0).WriteLn(); ...
One of the lines above will throw an exception. Which one is it? Well, the one where Obj1 is casted to a string. I'm not entirely certain what's happening here.
I've no idea whether it was Microsof't's implementation of Java's Hashmap that is problematic, or whether Sun's Java specification is problematic, or whether the problem lies with CodeGear's dccil compiler, or whether my translation is at fault.
If, instead of casting to a string, I use Obj1.ToString instead, the code then works flawlessly though... One of the ways I work around this issue is by declaring the LHS variable to be a TObject, or a System.Object, and then calling LHS.ToString instead.
In 2017, with the release of Delphi 10.2 Tokyo, Embarcadero introduced a specialized implementation of the Observer pattern into the System.Classes unit. While it has been in the wild for 9 years, it remains a "hidden" architecture for many, primarily because it serves as the invisible engine behind LiveBindings. Other than live bindings, you can also use the Observer pattern as a way to update component settings to the Windows registry, an .ini file, or persist it elsewhere.
System.Classes