diff --git a/CHANGES.md b/CHANGES.md
index a8d0f9858c..9513d4766e 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -36,6 +36,11 @@ Breaking Changes
`com.sun.jna.Pointer#setWideString(long offset, String value)`
* `com.sun.jna.Structure#setFieldOrder` is removed. It was replaced by
`com.sun.jna.Structure#getFieldOrder` and threw an `java.lang.Error` on call.
+* In `com.sun.jna.Structure` the signature of the `newInstance` methods
+ was modified. The signature was: `Structure newInstance(Class> type)` requiring
+ an explicit cast after the call. The the new signature introduces a type parameter `T`
+ with an upper bound of `com.sun.jna.Structure`:
` T newInstance(Class type)`
+ The companion, that takes an init pointer was also updated:
` T newInstance(Class type, Pointer init)`
* `com.sun.jna.Native#parseVersion` was removed without replacement
* `com.sun.jna.Native#setPreserveLastError` and `com.sun.jna.Native#getPreserveLastError`
were removed without replacement. They were turned into NOOPs in the past.
diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Winevt.java b/contrib/platform/src/com/sun/jna/platform/win32/Winevt.java
index 9ce7d5cebc..71a46e0ec2 100644
--- a/contrib/platform/src/com/sun/jna/platform/win32/Winevt.java
+++ b/contrib/platform/src/com/sun/jna/platform/win32/Winevt.java
@@ -488,7 +488,7 @@ public Object getValue() {
return isArray() ? field1.getPointer().getPointer(0).getWideStringArray(0, Count) : field1.getPointer().getPointer(0).getWideString(0);
case EvtVarTypeFileTime:
if (isArray()) {
- WinBase.FILETIME resultFirst = (WinBase.FILETIME) Structure.newInstance(WinBase.FILETIME.class, field1.getPointer().getPointer(0));
+ WinBase.FILETIME resultFirst = Structure.newInstance(WinBase.FILETIME.class, field1.getPointer().getPointer(0));
resultFirst.read();
return resultFirst.toArray(Count);
} else {
@@ -498,11 +498,11 @@ public Object getValue() {
}
case EvtVarTypeSysTime:
if (isArray()) {
- WinBase.SYSTEMTIME resultFirst = (WinBase.SYSTEMTIME) Structure.newInstance(WinBase.SYSTEMTIME.class, field1.getPointer().getPointer(0));
+ WinBase.SYSTEMTIME resultFirst = Structure.newInstance(WinBase.SYSTEMTIME.class, field1.getPointer().getPointer(0));
resultFirst.read();
return resultFirst.toArray(Count);
} else {
- WinBase.SYSTEMTIME result = (WinBase.SYSTEMTIME) Structure.newInstance(WinBase.SYSTEMTIME.class, field1.getPointer().getPointer(0));
+ WinBase.SYSTEMTIME result = Structure.newInstance(WinBase.SYSTEMTIME.class, field1.getPointer().getPointer(0));
result.read();
return result;
}
@@ -531,21 +531,21 @@ public Object getValue() {
return null;
case EvtVarTypeGuid:
if (isArray()) {
- Guid.GUID resultFirst = (Guid.GUID) Structure.newInstance(Guid.GUID.class, field1.getPointer().getPointer(0));
+ Guid.GUID resultFirst = Structure.newInstance(Guid.GUID.class, field1.getPointer().getPointer(0));
resultFirst.read();
return resultFirst.toArray(Count);
} else {
- Guid.GUID result = (Guid.GUID) Structure.newInstance(Guid.GUID.class, field1.getPointer().getPointer(0));
+ Guid.GUID result = Structure.newInstance(Guid.GUID.class, field1.getPointer().getPointer(0));
result.read();
return result;
}
case EvtVarTypeSid:
if (isArray()) {
- WinNT.PSID resultFirst = (WinNT.PSID) Structure.newInstance(WinNT.PSID.class, field1.getPointer().getPointer(0));
+ WinNT.PSID resultFirst = Structure.newInstance(WinNT.PSID.class, field1.getPointer().getPointer(0));
resultFirst.read();
return resultFirst.toArray(Count);
} else {
- WinNT.PSID result = (WinNT.PSID) Structure.newInstance(WinNT.PSID.class, field1.getPointer().getPointer(0));
+ WinNT.PSID result = Structure.newInstance(WinNT.PSID.class, field1.getPointer().getPointer(0));
result.read();
return result;
}
diff --git a/src/com/sun/jna/CallbackReference.java b/src/com/sun/jna/CallbackReference.java
index 5c9d62cd7d..8fcb34773d 100644
--- a/src/com/sun/jna/CallbackReference.java
+++ b/src/com/sun/jna/CallbackReference.java
@@ -272,7 +272,7 @@ private CallbackReference(Callback callback, int callingConvention, boolean dire
private Class> getNativeType(Class> cls) {
if (Structure.class.isAssignableFrom(cls)) {
// Make sure we can instantiate an argument of this type
- Structure.validate(cls);
+ Structure.validate((Class extends Structure>)cls);
if (!Structure.ByValue.class.isAssignableFrom(cls))
return Pointer.class;
} else if (NativeMapped.class.isAssignableFrom(cls)) {
@@ -580,14 +580,14 @@ else if (Structure.class.isAssignableFrom(dstType)) {
// If passed by value, don't hold onto the pointer, which
// is only valid for the duration of the callback call
if (Structure.ByValue.class.isAssignableFrom(dstType)) {
- Structure s = Structure.newInstance(dstType);
+ Structure s = Structure.newInstance((Class extends Structure>) dstType);
byte[] buf = new byte[s.size()];
((Pointer)value).read(0, buf, 0, buf.length);
s.getPointer().write(0, buf, 0, buf.length);
s.read();
value = s;
} else {
- Structure s = Structure.newInstance(dstType, (Pointer)value);
+ Structure s = Structure.newInstance((Class extends Structure>) dstType, (Pointer)value);
s.conditionalAutoRead();
value = s;
}
diff --git a/src/com/sun/jna/Function.java b/src/com/sun/jna/Function.java
index 795901d44b..2d31827f02 100644
--- a/src/com/sun/jna/Function.java
+++ b/src/com/sun/jna/Function.java
@@ -378,11 +378,11 @@ Object invoke(Method invokingMethod, Class>[] paramTypes, Class> returnType,
if (args[i] instanceof PointerArray) {
PointerArray array = (PointerArray)args[i];
if (Structure.ByReference[].class.isAssignableFrom(inArg.getClass())) {
- Class> type = inArg.getClass().getComponentType();
+ Class extends Structure> type = (Class extends Structure>) inArg.getClass().getComponentType();
Structure[] ss = (Structure[])inArg;
for (int si=0;si < ss.length;si++) {
Pointer p = array.getPointer(Native.POINTER_SIZE * si);
- ss[si] = Structure.updateStructureByReference(type, ss[si], p);
+ ss[si] = Structure.updateStructureByReference((Class)type, ss[si], p);
}
}
}
@@ -436,13 +436,13 @@ Object invoke(Object[] args, Class> returnType, boolean allowObjects, int fixe
if (Structure.ByValue.class.isAssignableFrom(returnType)) {
Structure s =
Native.invokeStructure(this, this.peer, callFlags, args,
- Structure.newInstance(returnType));
+ Structure.newInstance((Class extends Structure>)returnType));
s.autoRead();
result = s;
} else {
result = invokePointer(callFlags, args);
if (result != null) {
- Structure s = Structure.newInstance(returnType, (Pointer)result);
+ Structure s = Structure.newInstance((Class extends Structure>)returnType, (Pointer)result);
s.conditionalAutoRead();
result = s;
}
@@ -604,7 +604,7 @@ private Object convertArgument(Object[] args, int index,
} else if (ss.length == 0) {
throw new IllegalArgumentException("Structure array must have non-zero length");
} else if (ss[0] == null) {
- Structure.newInstance(type).toArray(ss);
+ Structure.newInstance((Class extends Structure>) type).toArray(ss);
return ss[0].getPointer();
} else {
Structure.autoWrite(ss);
diff --git a/src/com/sun/jna/Native.java b/src/com/sun/jna/Native.java
index 33e8e56008..ae80566609 100644
--- a/src/com/sun/jna/Native.java
+++ b/src/com/sun/jna/Native.java
@@ -1241,7 +1241,7 @@ public static int getNativeSize(Class> type, Object value) {
}
if (Structure.class.isAssignableFrom(type)
&& !Structure.ByReference.class.isAssignableFrom(type)) {
- return Structure.size(type, (Structure)value);
+ return Structure.size((Class) type, (Structure)value);
}
try {
return getNativeSize(type);
@@ -1276,7 +1276,7 @@ public static int getNativeSize(Class> cls) {
if (cls == double.class || cls == Double.class) return 8;
if (Structure.class.isAssignableFrom(cls)) {
if (Structure.ByValue.class.isAssignableFrom(cls)) {
- return Structure.size(cls);
+ return Structure.size((Class extends Structure>) cls);
}
return POINTER_SIZE;
}
diff --git a/src/com/sun/jna/Pointer.java b/src/com/sun/jna/Pointer.java
index 16ad03fd80..c111f9a7a6 100644
--- a/src/com/sun/jna/Pointer.java
+++ b/src/com/sun/jna/Pointer.java
@@ -363,7 +363,7 @@ Object getValue(long offset, Class> type, Object currentValue) {
if (Structure.class.isAssignableFrom(type)) {
Structure s = (Structure)currentValue;
if (Structure.ByReference.class.isAssignableFrom(type)) {
- s = Structure.updateStructureByReference(type, s, getPointer(offset));
+ s = Structure.updateStructureByReference((Class) type, s, getPointer(offset));
} else {
s.useMemory(this, (int)offset, true);
s.read();
@@ -488,13 +488,13 @@ else if (Structure.class.isAssignableFrom(cls)) {
if (Structure.ByReference.class.isAssignableFrom(cls)) {
Pointer[] parray = getPointerArray(offset, sarray.length);
for (int i=0;i < sarray.length;i++) {
- sarray[i] = Structure.updateStructureByReference(cls, sarray[i], parray[i]);
+ sarray[i] = Structure.updateStructureByReference((Class) cls, sarray[i], parray[i]);
}
}
else {
Structure first = sarray[0];
if (first == null) {
- first = Structure.newInstance(cls, share(offset));
+ first = Structure.newInstance((Class) cls, share(offset));
first.conditionalAutoRead();
sarray[0] = first;
}
@@ -940,7 +940,7 @@ private void writeArray(long offset, Object value, Class> cls) {
} else {
Structure first = sbuf[0];
if (first == null) {
- first = Structure.newInstance(cls, share(offset));
+ first = Structure.newInstance((Class) cls, share(offset));
sbuf[0] = first;
} else {
first.useMemory(this, (int)offset, true);
diff --git a/src/com/sun/jna/Structure.java b/src/com/sun/jna/Structure.java
index 5e4b7f7dfb..e1e3940072 100644
--- a/src/com/sun/jna/Structure.java
+++ b/src/com/sun/jna/Structure.java
@@ -662,7 +662,7 @@ private void setFieldValue(Field field, Object value, boolean overrideFinal) {
* @param address the native struct *
* @return Updated Structure.ByReference
object
*/
- static Structure updateStructureByReference(Class> type, Structure s, Pointer address) {
+ static T updateStructureByReference(Class type, T s, Pointer address) {
if (address == null) {
s = null;
}
@@ -670,7 +670,7 @@ static Structure updateStructureByReference(Class> type, Structure s, Pointer
if (s == null || !address.equals(s.getPointer())) {
Structure s1 = reading().get(address);
if (s1 != null && type.equals(s1.getClass())) {
- s = s1;
+ s = (T) s1;
s.autoRead();
}
else {
@@ -1042,7 +1042,7 @@ protected int calculateSize(boolean force) {
* @param type Structure subclass to check
* @return native size of the given Structure subclass
*/
- static int size(Class> type) {
+ static int size(Class extends Structure> type) {
return size(type, null);
}
@@ -1051,7 +1051,7 @@ static int size(Class> type) {
* @param value optional instance of the given class
* @return native size of the Structure subclass
*/
- static int size(Class> type, Structure value) {
+ static int size(Class type, T value) {
LayoutInfo info;
synchronized(layoutInfo) {
info = layoutInfo.get(type);
@@ -1329,7 +1329,7 @@ private Object initializeField(Field field, Class> type) {
if (Structure.class.isAssignableFrom(type)
&& !(ByReference.class.isAssignableFrom(type))) {
try {
- value = newInstance(type, PLACEHOLDER_MEMORY);
+ value = newInstance((Class extends Structure>) type, PLACEHOLDER_MEMORY);
setFieldValue(field, value);
}
catch(IllegalArgumentException e) {
@@ -1408,7 +1408,7 @@ else if (Structure.class.isAssignableFrom(type)) {
}
else {
if (value == null)
- value = newInstance(type, PLACEHOLDER_MEMORY);
+ value = newInstance((Class extends Structure>) type, PLACEHOLDER_MEMORY);
alignment = ((Structure)value).getStructAlignment();
}
}
@@ -1744,7 +1744,7 @@ static Pointer getTypeInfo(Object obj) {
* #newInstance(Class,Pointer)}, except that it additionally calls
* {@link #conditionalAutoRead()}.
*/
- private static Structure newInstance(Class> type, long init) {
+ private static Structure newInstance(Class extends Structure> type, long init) {
try {
Structure s = newInstance(type, init == 0 ? PLACEHOLDER_MEMORY : new Pointer(init));
if (init != 0) {
@@ -1765,10 +1765,10 @@ private static Structure newInstance(Class> type, long init) {
* @return the new instance
* @throws IllegalArgumentException if the instantiation fails
*/
- public static Structure newInstance(Class> type, Pointer init) throws IllegalArgumentException {
+ public static T newInstance(Class type, Pointer init) throws IllegalArgumentException {
try {
- Constructor> ctor = type.getConstructor(Pointer.class);
- return (Structure)ctor.newInstance(init);
+ Constructor ctor = type.getConstructor(Pointer.class);
+ return ctor.newInstance(init);
}
catch(NoSuchMethodException e) {
// Not defined, fall back to the default
@@ -1789,7 +1789,7 @@ public static Structure newInstance(Class> type, Pointer init) throws IllegalA
e.printStackTrace();
throw new IllegalArgumentException(msg, e);
}
- Structure s = newInstance(type);
+ T s = newInstance(type);
if (init != PLACEHOLDER_MEMORY) {
s.useMemory(init);
}
@@ -1801,9 +1801,9 @@ public static Structure newInstance(Class> type, Pointer init) throws IllegalA
* @return the new instance
* @throws IllegalArgumentException if the instantiation fails
*/
- public static Structure newInstance(Class> type) throws IllegalArgumentException {
+ public static T newInstance(Class type) throws IllegalArgumentException {
try {
- Structure s = (Structure)type.newInstance();
+ T s = type.newInstance();
if (s instanceof ByValue) {
s.allocateMemory();
}
@@ -1993,7 +1993,7 @@ private static Pointer get(Object obj, Class> cls) {
return FFITypes.ffi_type_pointer;
}
if (Structure.class.isAssignableFrom(cls)) {
- if (obj == null) obj = newInstance(cls, PLACEHOLDER_MEMORY);
+ if (obj == null) obj = newInstance((Class extends Structure>) cls, PLACEHOLDER_MEMORY);
if (ByReference.class.isAssignableFrom(cls)) {
typeInfoMap.put(cls, FFITypes.ffi_type_pointer);
return FFITypes.ffi_type_pointer;
@@ -2124,7 +2124,7 @@ protected int getNativeSize(Class> nativeType, Object value) {
/** Indicate whether the given Structure class can be created by JNA.
* @param cls Structure subclass to check
*/
- static void validate(Class> cls) {
+ static void validate(Class extends Structure> cls) {
Structure.newInstance(cls, PLACEHOLDER_MEMORY);
}
}
diff --git a/test/com/sun/jna/StructureTest.java b/test/com/sun/jna/StructureTest.java
index 21f80f620e..1752672fbe 100644
--- a/test/com/sun/jna/StructureTest.java
+++ b/test/com/sun/jna/StructureTest.java
@@ -281,7 +281,7 @@ public interface SizeTest extends Library {
private void testStructureSize(int index) {
try {
SizeTest lib = Native.loadLibrary("testlib", SizeTest.class);
- Class> cls = Class.forName(getClass().getName() + "$TestStructure" + index);
+ Class extends Structure> cls = (Class extends Structure>) Class.forName(getClass().getName() + "$TestStructure" + index);
Structure s = Structure.newInstance(cls);
assertEquals("Incorrect size for structure " + index + "=>" + s.toString(true), lib.getStructureSize(index), s.size());
}