On Mon, 20 Sep 2021 16:55:49 GMT, Brett Okken 
<[email protected]> wrote:

>> I wrote a simple example which uses DLC and lazy initialization holder class 
>> idioms. The FontManager is only created when it is accessed the first time 
>> via the getInstance() method in both cases and they both fail if an 
>> exception is thrown during the class initialization.
>> 
>> Is the problem with Holder idiom that it throws 
>> `ExceptionInInitializerError` which contains the original exception as the 
>> cause whereas with DLC the original exception is directly thrown?
>> 
>> public class FontManagerFactory {
>> 
>>     private static volatile FontManager instance;
>> 
>>     public static FontManager getInstanceDLC() {
>> 
>>         FontManager result = instance;
>>         if (result == null) {
>>             synchronized (FontManagerFactory.class) {
>>                 result = instance;
>>                 if (result == null) {
>>                     instance = result = new FontManager("One", "Two", 
>> "Three");
>>                 }
>>             }
>>         }
>>         return result;
>>     }
>> 
>>     public static FontManager getInstanceHolder() {
>>         return FontManagerHolder.instance;
>>     }
>> 
>> 
>>     public static void main(String[] args) {
>>         String lazyInitializationIdiom = args[0];
>>         System.out.printf("Use lazy initialization idiom: %s%n", 
>> lazyInitializationIdiom);
>>         if ("DLC".equals(args[0])) {
>>             System.out.printf("DLC FontManager instance: %s%n", 
>> getInstanceDLC());
>>         } else if ("Holder".equals(args[0])) {
>>             System.out.printf("Lazy Initialization Holder FontManager 
>> instance: %s%n", getInstanceHolder());
>>         }
>>     }
>> 
>>     private static class FontManagerHolder {
>>         private static final FontManager instance = new FontManager("One", 
>> "Two", "Three");
>>     }
>> }
>> 
>> class FontManager {
>>     public FontManager(String... args) {
>>         System.out.println(args[5]);
>>     }
>> }
>> ``` 
>> DLC:
>> 
>> java FontManagerFactory DLC
>> Use lazy initialization idiom: DLC
>> Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 5 
>> out of bounds for length 3
>>      at FontManager.<init>(FontManagerFactory.java:41)
>>      at FontManagerFactory.getInstanceDLC(FontManagerFactory.java:12)
>>      at FontManagerFactory.main(FontManagerFactory.java:28)
>> 
>> Hodler:
>> 
>> java FontManagerFactory Holder
>> Use lazy initialization idiom: Holder
>> Exception in thread "main" java.lang.ExceptionInInitializerError
>>      at FontManagerFactory.getInstanceHolder(FontManagerFactory.java:20)
>>      at FontManagerFactory.main(FontManagerFactory.java:30)
>> Caused by: java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds 
>> for length 3
>>      at FontManager.<init>(FontManagerFactory.java:41)
>>      at 
>> FontManagerFactory$FontManagerHolder.<clinit>(FontManagerFactory.java:35)
>>      ... 2 more
>
> Does that stack trace difference really matter?
> if so, you could wrap the `return FontManagerHolder.instance;` in a try/catch 
> that throws that caused by:
> 
> 
> try {
>   return FontManagerHolder.instance;
> } catch (java.lang.ExceptionInInitializerError e) {
>   final Throwable cause = e.getCause();
>   if (cause instanceof RuntimeException re) {
>     throw re;
>   }
>   //could wrap in IllegalStateException or just throw the error
> }
> 
> 
> If this getInstance method is called with any frequency, getting rid of the 
> volatile access each time is a nice bonus.

The difference is that Holder will fail that way forever, while the DLC have a 
chance to resurrect on next call.

-------------

PR: https://git.openjdk.java.net/jdk/pull/5517

Reply via email to