diff --git a/src/com/sun/jna/Structure.java b/src/com/sun/jna/Structure.java index 86a3acff8..2bf4c8c40 100644 --- a/src/com/sun/jna/Structure.java +++ b/src/com/sun/jna/Structure.java @@ -157,6 +157,8 @@ private static class NativeStringTracking { protected static final int CALCULATE_SIZE = -1; static final Map, LayoutInfo> layoutInfo = new WeakHashMap<>(); static final Map, List> fieldOrder = new WeakHashMap<>(); + static final Map, List> fieldList = new WeakHashMap<>(); + static final Map, Boolean> validationMap = new WeakHashMap<>(); // This field is accessed by native code private Pointer memory; @@ -1015,22 +1017,26 @@ protected void sortFields(List fields, List names) { * this {@link Structure} class. */ protected List getFieldList() { - List flist = new ArrayList<>(); - for (Class cls = getClass(); - !cls.equals(Structure.class); - cls = cls.getSuperclass()) { - List classFields = new ArrayList<>(); - Field[] fields = cls.getDeclaredFields(); - for (int i=0;i < fields.length;i++) { - int modifiers = fields[i].getModifiers(); - if (Modifier.isStatic(modifiers) || !Modifier.isPublic(modifiers)) { - continue; + synchronized (fieldList) { + return fieldList.computeIfAbsent(getClass(), (c) -> { + List flist = new ArrayList<>(); + List classFields = new ArrayList<>(); + for (Class cls = getClass(); + !cls.equals(Structure.class); + cls = cls.getSuperclass()) { + for (Field field : cls.getDeclaredFields()) { + int modifiers = field.getModifiers(); + if (Modifier.isStatic(modifiers) || !Modifier.isPublic(modifiers)) { + continue; + } + classFields.add(field); + } + flist.addAll(0, classFields); + classFields.clear(); } - classFields.add(fields[i]); - } - flist.addAll(0, classFields); + return flist; + }); } - return flist; } /** Cache field order per-class. @@ -1039,12 +1045,7 @@ protected List getFieldList() { private List fieldOrder() { Class clazz = getClass(); synchronized(fieldOrder) { - List list = fieldOrder.get(clazz); - if (list == null) { - list = getFieldOrder(); - fieldOrder.put(clazz, list); - } - return list; + return fieldOrder.computeIfAbsent(clazz, (c) -> getFieldOrder()); } } @@ -1250,9 +1251,13 @@ private void validateField(String name, Class type) { /** ensure all fields are of valid type. */ private void validateFields() { - List fields = getFieldList(); - for (Field f : fields) { - validateField(f.getName(), f.getType()); + synchronized (validationMap) { + validationMap.computeIfAbsent(getClass(), (cls) -> { + for (Field f : getFieldList()) { + validateField(f.getName(), f.getType()); + } + return true; + }); } }