Don't use reflection when possible Signed-off-by: Lukáš Petrovický <lukas@petrovicky.net>
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; } }