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;
}
}