所以我在jdk 7上运行了这两个类:
abstract class Aclass
{
public void foo()
{
}
public void bar()
{
}
}
和
public class Bclass extends Aclass
{
public void foo(Integer one)
{
}
public void bar(String two)
{
}
}
我的目标是加载Bclass和Bclass ONLY,打印出声明的方法和那些声明的方法的参数。 这是我使用的代码:
public static void main(String[] args)
{
try
{
Class<?> clazz = Tester.class.getClassLoader().loadClass("full_path.Bclass");
for (Method method : clazz.getDeclaredMethods())
{
System.out.println("Method name: " + method.getName() + " From class: " + method.getDeclaringClass().getCanonicalName() + " with declared methods:");// test
for (Class<?> param : method.getParameterTypes())
{
System.out.println(param.getCanonicalName());
}
}
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
}
运行此代码会产生以下输出:
Method name: foo From class: complete_path.Bclass with declared methods:
Method name: foo From class: complete_path.Bclass with declared methods:
java.lang.Integer
Method name: bar From class: complete_path.Bclass with declared methods:
Method name: bar From class: complete_path.Bclass with declared methods:
java.lang.String
但是在方法[getDeclaredMethods()]的javadoc中,我看到but excludes inherited methods
,根据我的测试,这似乎并非如此,该方法显然会在重载时加载继承的方法。
或者我做错了什么?
答案 0 :(得分:2)
我的目标是加载Bclass和Bclass ONLY ......
这是不可能的。
JVM规范(Chapter 5)详细解释了加载类时会发生什么。必须发生的事情之一是解析对直接超类和接口的引用。这需要加载相应的类/接口。
如果(由于某种原因)无法加载超类或接口,则加载子类失败。
加载java类方法,文档与方法的行为不一致
getDeclaredMethods()
的意外行为是另一个问题。它与类加载无关。
根据此Q&amp; A - Problem in the GetDeclaredMethods (java) - 您正在看到合成&#34;桥接&#34;已添加到Bclass
的方法,而不是从Aclass
继承的方法。
桥接方法在Java教程here中进行了描述。
您可以使用javap Bclass
查看Bclass.class
中的代码来确认此问题。请参阅输出中的那些额外桥接方法。
[steve@newbox tmp]$ javap Bclass
Compiled from "Bclass.java"
public class Bclass extends Aclass {
public Bclass();
public void foo(java.lang.Integer);
public void bar(java.lang.String);
public void bar();
public void foo();
}
可以通过为每个method.isBridge()
对象打印Method
来进一步确认(如果需要)。
现在我不明白为什么这个代码需要桥接方法......但这就是它们。
总结:您看到的getDeclaredMethods
的行为与javadocs一致。您所看到的是最近Java实现的鲜为人知的(但记录!)方面的结果。
答案 1 :(得分:1)
这很奇怪
我认为我没有做错任何事,但我运行你的程序,它只打印Bclass
中的方法。我刚刚更改了包,我将Aclass
和Bclass
放在同一个文件中,因为只有Bclass
是public
。输出:
Method name: foo From class: test2.Bclass with declared methods:
java.lang.Integer
Method name: bar From class: test2.Bclass with declared methods:
java.lang.String
test2.Bclass
test2.Aclass
// Also added at the end
// System.out.println(clazz.getCanonicalName());
// System.out.println(clazz.getSuperclass().getCanonicalName());
// to see if I typed something wrong.
编译并运行:Sun JDK 1.5.0_22。