Merge pull request #401 from triceo/lessreflection

Don't use reflection when possible
diff --git a/src/main/java/org/eclipse/yasson/internal/model/ClassModel.java b/src/main/java/org/eclipse/yasson/internal/model/ClassModel.java
index fe66c50..64a33b5 100644
--- a/src/main/java/org/eclipse/yasson/internal/model/ClassModel.java
+++ b/src/main/java/org/eclipse/yasson/internal/model/ClassModel.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0 which is available at
@@ -18,6 +18,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.stream.Collectors;
 
 import javax.json.bind.config.PropertyNamingStrategy;
@@ -37,7 +38,9 @@
 
     private final ClassModel parentClassModel;
 
-    private final Constructor<?> defaultConstructor;
+    private final AtomicBoolean isInitialized = new AtomicBoolean(false);
+
+    private Constructor<?> defaultConstructor;
 
     /**
      * A map of all class properties, including properties from superclasses. Used to access by name.
@@ -77,7 +80,6 @@
         this.classCustomization = customization;
         this.parentClassModel = parentClassModel;
         this.propertyNamingStrategy = propertyNamingStrategy;
-        this.defaultConstructor = ReflectionUtils.getDefaultConstructor(clazz, false);
         setProperties(new ArrayList<>());
     }
 
@@ -183,6 +185,13 @@
      * @return default constructor
      */
     public Constructor<?> getDefaultConstructor() {
+        // Lazy-loads the default constructor to avoid Java 9+ "Illegal reflective access" warnings where possible.
+        // Example: Deserialization into Map won't use this constructor, and therefore never needs to call this method.
+        // Note: Null is a valid result and needs to be cached.
+        if (!isInitialized.get()) {
+            defaultConstructor = ReflectionUtils.getDefaultConstructor(clazz, false);
+            isInitialized.set(true);
+        }
         return defaultConstructor;
     }
 }