aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/main/javassist/CtClassType.java2
-rw-r--r--src/main/javassist/CtMethod.java24
-rw-r--r--src/main/javassist/bytecode/ClassFile.java2
-rw-r--r--src/main/javassist/bytecode/Descriptor.java15
-rw-r--r--src/main/javassist/reflect/ClassMetaobject.java26
-rw-r--r--src/main/javassist/reflect/Reflection.java11
6 files changed, 48 insertions, 32 deletions
diff --git a/src/main/javassist/CtClassType.java b/src/main/javassist/CtClassType.java
index fa60df73..cda8fd36 100644
--- a/src/main/javassist/CtClassType.java
+++ b/src/main/javassist/CtClassType.java
@@ -666,7 +666,7 @@ class CtClassType extends CtClass {
CtMethod cm = ((CtClassType)cc).getMethodsCache();
while (cm != null) {
if (Modifier.isPublic(cm.getModifiers()))
- h.put(cm, cm);
+ h.put(cm.getStringRep(), cm);
cm = cm.next;
}
diff --git a/src/main/javassist/CtMethod.java b/src/main/javassist/CtMethod.java
index f0547150..9d9416b3 100644
--- a/src/main/javassist/CtMethod.java
+++ b/src/main/javassist/CtMethod.java
@@ -28,12 +28,12 @@ import javassist.bytecode.*;
*/
public final class CtMethod extends CtBehavior {
protected CtMethod next;
- protected int cachedHashCode;
+ protected String cachedStringRep;
CtMethod(MethodInfo minfo, CtClass declaring) {
super(declaring, minfo);
next = null;
- cachedHashCode = 0;
+ cachedStringRep = null;
}
/**
@@ -163,17 +163,17 @@ public final class CtMethod extends CtBehavior {
* the hash codes for the two methods are equal.
*/
public int hashCode() {
- /* This method is overridden in ExistingMethod for optimization.
- */
- if (cachedHashCode == 0) {
- String signature
- = methodInfo.getName() + ':' + methodInfo.getDescriptor();
+ return getStringRep().hashCode();
+ }
- // System.identityHashCode() returns 0 only for null.
- cachedHashCode = System.identityHashCode(signature.intern());
- }
+ /* This method is also called by CtClassType.getMethods0().
+ */
+ final String getStringRep() {
+ if (cachedStringRep == null)
+ cachedStringRep = methodInfo.getName()
+ + Descriptor.getParamDescriptor(methodInfo.getDescriptor());
- return cachedHashCode;
+ return cachedStringRep;
}
/**
@@ -182,7 +182,7 @@ public final class CtMethod extends CtBehavior {
*/
public boolean equals(Object obj) {
return obj != null && obj instanceof CtMethod
- && obj.hashCode() == hashCode();
+ && ((CtMethod)obj).getStringRep().equals(getStringRep());
}
/**
diff --git a/src/main/javassist/bytecode/ClassFile.java b/src/main/javassist/bytecode/ClassFile.java
index d9b6dfa6..4f85f667 100644
--- a/src/main/javassist/bytecode/ClassFile.java
+++ b/src/main/javassist/bytecode/ClassFile.java
@@ -452,7 +452,7 @@ public final class ClassFile {
while (it.hasNext()) {
MethodInfo minfo = (MethodInfo)it.next();
if (minfo.getName().equals(name)
- && Descriptor.eqSignature(minfo.getDescriptor(), descriptor))
+ && Descriptor.eqParamTypes(minfo.getDescriptor(), descriptor))
throw new CannotCompileException("duplicate method: " + name);
}
}
diff --git a/src/main/javassist/bytecode/Descriptor.java b/src/main/javassist/bytecode/Descriptor.java
index 4a352aaf..54ee506b 100644
--- a/src/main/javassist/bytecode/Descriptor.java
+++ b/src/main/javassist/bytecode/Descriptor.java
@@ -337,9 +337,11 @@ public class Descriptor {
}
/**
- * Returns true if desc1 and desc2 has the same signature.
+ * Returns true if the list of the parameter types of desc1 is equal to
+ * that of desc2.
+ * For example, "(II)V" and "(II)I" are equal.
*/
- public static boolean eqSignature(String desc1, String desc2) {
+ public static boolean eqParamTypes(String desc1, String desc2) {
if (desc1.charAt(0) != '(')
return false;
@@ -354,6 +356,15 @@ public class Descriptor {
}
/**
+ * Returns the signature of the given descriptor. The signature does
+ * not include the return type. For example, the signature of "(I)V"
+ * is "(I)".
+ */
+ public static String getParamDescriptor(String decl) {
+ return decl.substring(0, decl.indexOf(')') + 1);
+ }
+
+ /**
* Returns the <code>CtClass</code> object representing the return
* type specified by the given descriptor.
*
diff --git a/src/main/javassist/reflect/ClassMetaobject.java b/src/main/javassist/reflect/ClassMetaobject.java
index 000846af..6d43b0e6 100644
--- a/src/main/javassist/reflect/ClassMetaobject.java
+++ b/src/main/javassist/reflect/ClassMetaobject.java
@@ -249,25 +249,23 @@ public class ClassMetaobject implements Serializable {
return methods;
Class baseclass = getJavaClass();
- Method[] allmethods = baseclass.getMethods();
+ Method[] allmethods = baseclass.getDeclaredMethods();
int n = allmethods.length;
methods = new Method[n];
for (int i = 0; i < n; ++i) {
Method m = allmethods[i];
- if (m.getDeclaringClass() == baseclass) {
- String mname = m.getName();
- if (mname.startsWith(methodPrefix)) {
- int k = 0;
- for (int j = methodPrefixLen;; ++j) {
- char c = mname.charAt(j);
- if ('0' <= c && c <= '9')
- k = k * 10 + c - '0';
- else
- break;
- }
-
- methods[k] = m;
+ String mname = m.getName();
+ if (mname.startsWith(methodPrefix)) {
+ int k = 0;
+ for (int j = methodPrefixLen;; ++j) {
+ char c = mname.charAt(j);
+ if ('0' <= c && c <= '9')
+ k = k * 10 + c - '0';
+ else
+ break;
}
+
+ methods[k] = m;
}
}
diff --git a/src/main/javassist/reflect/Reflection.java b/src/main/javassist/reflect/Reflection.java
index a52351da..014a6152 100644
--- a/src/main/javassist/reflect/Reflection.java
+++ b/src/main/javassist/reflect/Reflection.java
@@ -24,8 +24,11 @@ import javassist.CtMethod.ConstParameter;
* <p>If a class is reflective,
* then all the method invocations on every
* instance of that class are intercepted by the runtime
- * metaobject controlling that instance.
- * To do this, the original class file representing a reflective class:
+ * metaobject controlling that instance. The methods inherited from the
+ * super classes are also intercepted except final methods. To intercept
+ * a final method in a super class, that super class must be also reflective.
+ *
+ * <p>To do this, the original class file representing a reflective class:
*
* <ul><pre>
* class Person {
@@ -298,6 +301,10 @@ public class Reflection implements Translator {
return;
m2 = m;
+ if (Modifier.isFinal(mod)) {
+ mod &= ~Modifier.FINAL;
+ m2.setModifiers(mod);
+ }
}
else {
if (Modifier.isFinal(mod))