正在加载 java class 方法,文档与方法的行为不一致
Loading java class methods, docs not consistent with method's behavior
所以我有 2 类 运行 在 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,打印出其声明的方法和那些声明的方法的参数。
这是我使用的代码:
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
,根据我的测试,情况似乎并非如此,该方法显然会在重载时加载继承的方法。
还是我做错了什么?
My goal is to load Bclass, and Bclass ONLY ...
不可能。
JVM 规范 (Chapter 5) 非常详细地解释了加载 class 时必须发生的情况。必须发生的事情之一是对直接 superclasses 和接口的引用被解析。这需要加载相应的 classes / 接口。
如果(出于某种原因)无法加载超级classes 或接口,则加载子 class 失败。
Loading java class methods, docs not consistent with method's behavior
getDeclaredMethods()
的意外行为是另一个问题。与class加载无关。
根据此问答 - Problem in the GetDeclaredMethods (java) - 您看到合成 "bridge" 方法已添加到 Bclass
而不是从 Aclass
.[=24 继承的方法=]
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
对象打印 method.isBridge()
来进一步确认(如果需要)。
现在我不明白为什么这个代码需要桥接方法...但这就是它们。
总而言之:您看到的 getDeclaredMethods
的行为 与 javadoc 一致。您所看到的是最近 Java 实施的 鲜为人知 (但已记录!)方面的结果。
很奇怪
我想我没有做错,但我 运行 你的程序,它只打印 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。
所以我有 2 类 运行 在 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,打印出其声明的方法和那些声明的方法的参数。 这是我使用的代码:
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
,根据我的测试,情况似乎并非如此,该方法显然会在重载时加载继承的方法。
还是我做错了什么?
My goal is to load Bclass, and Bclass ONLY ...
不可能。
JVM 规范 (Chapter 5) 非常详细地解释了加载 class 时必须发生的情况。必须发生的事情之一是对直接 superclasses 和接口的引用被解析。这需要加载相应的 classes / 接口。
如果(出于某种原因)无法加载超级classes 或接口,则加载子 class 失败。
Loading java class methods, docs not consistent with method's behavior
getDeclaredMethods()
的意外行为是另一个问题。与class加载无关。
根据此问答 - Problem in the GetDeclaredMethods (java) - 您看到合成 "bridge" 方法已添加到 Bclass
而不是从 Aclass
.[=24 继承的方法=]
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
对象打印 method.isBridge()
来进一步确认(如果需要)。
现在我不明白为什么这个代码需要桥接方法...但这就是它们。
总而言之:您看到的 getDeclaredMethods
的行为 与 javadoc 一致。您所看到的是最近 Java 实施的 鲜为人知 (但已记录!)方面的结果。
很奇怪
我想我没有做错,但我 运行 你的程序,它只打印 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。