Skip to content

Commit 38a1e86

Browse files
A partial solution for Class object singletons
This is necessary to make comparisons such as o.getClass() == o.getClass() succeed.
1 parent 33c3c6a commit 38a1e86

File tree

1 file changed

+22
-3
lines changed

1 file changed

+22
-3
lines changed

src/main/java/java/lang/Class.java

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,13 @@ private Class() {}
107107
private boolean cproverIsMemberClass;
108108
private boolean cproverIsEnum;
109109

110+
// TODO: these fields are to enforce singleton semantics of
111+
// Class objects as returned by Object.getClass() and Class.forName()
112+
// The size is currently hard-coded which may lead to incorrect results.
113+
// A map could be used here in future.
114+
private static String[] cproverClassNames = new String[8];
115+
private static Class<?>[] cproverClassInstances = new Class<?>[8];
116+
110117
public String toString() {
111118
return (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))
112119
+ getName();
@@ -163,9 +170,21 @@ public String toGenericString() {
163170
// forName method. The goal is to correctly model combinations of forName
164171
// and getName, but precisely following the JDK behaviour is more involved.
165172
public static Class<?> forName(String className) {
166-
Class c=new Class();
167-
c.name=className;
168-
return c;
173+
String foundName = null;
174+
for (int i = 0; i < cproverClassNames.length; ++i) {
175+
String currentName = cproverClassNames[i];
176+
if (currentName == null) {
177+
Class<?> c = new Class();
178+
c.name = className;
179+
cproverClassNames[i] = className;
180+
cproverClassInstances[i] = c;
181+
return c;
182+
}
183+
if (className.equals(currentName)) {
184+
return cproverClassInstances[i];
185+
}
186+
}
187+
return CProver.nondetWithoutNullForNotModelled();
169188
}
170189

171190
public static Class<?> forName(String name, boolean initialize,

0 commit comments

Comments
 (0)