`
webcode
  • 浏览: 6065920 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

一个有趣的Java编译问题

阅读更多

学员冯伟立今天中午问了我一个有趣的Java编译问题,我也无法给他解释,不知道有没有路过的高人能够解释清楚原因,望不吝赐教!
下面程序的main方法中的第二行代码和注释中的两行代码表达的意思完全相同,注释中的两行代码不能通过编译(这很容易理解),而第二行(采用方法调用链)却可以顺利通过编译(这就很难理解了)。
public class Test
{
public void func()
{
System.out.println("func");
}

public static void main(String args[]) throws Exception
{
Object obj = new Test();

//下面这行可以成功编译
((Test)obj).getClass().newInstance().func();

//下面这两行无法通过编译
/*Class c = ((Test)obj).getClass();
c.newInstance().func();*/

}
}

感谢paulex先生的帮助,在paulex先生的提示下,我基本上明白了上述问题的原因。下面是paulex先生的解答:

-----------------------------------------------------------------------------------------------------------------------

paulex发表于2006-11-08 08:09:00IP: 10.0.0.*
因为Generic, 编译器可以在编译期获得类型信息所以可以编译这类代码。你将下面那两行改成

Class<? extends Test> c = ((Test)obj).getClass();
c.newInstance().func();

应该就能通过编译了。

楼上的用1.4.2的编译器所以不能编译。
-------------------------------------------------------------------------------------------------------------------------
下面是我在paulex先生解答的基础上,对问题的进一步解释:
在JDK 1.5中引入范型后,Object.getClass()方法的定义如下:
public final Class<? extends Object> getClass()
Returns the runtime class of an object. That Class object is the object that is locked by static synchronized methods of the represented class.
Returns:
The java.lang.Class object that represents the runtime class of the object. The result is of type Class<? extends X> where X is the erasure of the static type of the expression on which getClass is called.

这说明((Test)obj).getClass()语句返回的对象类型为Class<? extends Test>,而Class<T>的newInstance()方法的定义如下:
public T newInstance() throws InstantiationException,IllegalAccessException
即对于编译器看来,Class<Test>的newInstance()方法的对象类型为Test,而((Test)obj).getClass()返回的为对象类型为Class<? extends Test>,所以,编译器认为((Test)obj).getClass().newInstance()返回的对象类型为Test。

下面这两行代码之所以无法通过编译
Class c = ((Test)obj).getClass();
c.newInstance().func();
是因为((Test)obj).getClass()返回的为对象类型为Class<? extends Test>,但是我们在第一行将结果强制转换成了Class,然后再去调用Class的newInstance方法,而不是去调用Class<Test>的newInstance方法,编译器当然不再认为Class的newInstance方法返回的对象为Test了。

-------------------------------------------------------

再次向paulex先生表示感谢,paulex先生的blog地址是http://blog.csdn.net/paulex

分享到:
评论

相关推荐

    JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具

    JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA...

    java编译软件大全

    Java编译软件大全是针对Java源代码进行反编译的一系列工具集合,这些工具在软件开发、代码分析、逆向工程等领域中有着广泛的应用。在Java编程中,源代码通常是不可见的,因为它们被编译成字节码(.class文件),而...

    java反编译工具

    4. Krakatau:Krakatau是一个专注于解析和生成Java字节码的工具集,它可以反编译字节码,同时也支持编译Java源代码。 使用这些工具时,需要注意的是,反编译可能会导致源代码的格式和注释丢失,而且反编译的代码...

    java反编译工具绿色版

    "jd-gui反编译工具"是Java反编译领域中的一款知名工具,它提供了一个图形用户界面(GUI),使得用户可以直观地查看和分析字节码。用户可以打开单个.class文件或整个.jar文件,jd-gui会显示对应的源代码。此外,这款...

    java反编译程序

    **Procyon** 是一个全面的Java编译器和反编译器套件,除了反编译功能,它还支持编译和语法分析。Procyon生成的源代码质量高,尤其是在处理Java 8及更高版本时表现优秀。 反编译在以下场景中尤其有用: 1. **代码...

    java反编译exe

    然而,出于调试、学习或者逆向工程的目的,有时我们需要查看一个已编译的Java类文件的源代码,这时就需要用到反编译工具。标题中的“jd_gui.exe”就是一种常用的Java反编译工具,名为JadGUI。 JadGUI是Jad的图形...

    JavaCompiler --JDK6 API的简介(java动态编译)

    JavaCompiler 是 Java 中的一个编译器接口,提供了编译 Java 源代码的功能。在 Java SE6 中,JavaCompiler 接口是 javax.tools 包的一部分,提供了标准的方式来操作 Java 编译器。 使用 JavaCompiler 接口来编译 ...

    JAVA反编译软件(可将class文件反编译为java文件)

    Java反编译是Java开发中一个重要的辅助工具,它能够帮助开发者查看已编译的`.class`文件中的源代码,即使原始的`.java`源文件已经丢失或未被提供。这个过程对于理解类库的工作原理、逆向工程、调试、学习或者分析...

    java jar反编译工具 java Class反编译工具

    如果你需要反编译一个.jar文件,可以: 1. 右键点击.jar文件,选择“Open with” -&gt; JD-GUI。如果系统没有关联,你也可以通过“File” -&gt; “Open Archive”手动打开。 2. 在JD-GUI中,jar文件的内容将以目录结构的...

    java class反编译工具

    在描述中提到的工具,是一个小巧而实用的Java Class反编译器,用户只需运行`.exe`可执行文件,然后选择要反编译的`.class`文件,即可在指定目录下生成对应的`.java`文件。 Java字节码是Java源代码经过编译后的中间...

    java反编译软件,可以将编译后的class文件反编译成java文件

    Java反编译是编程领域中的一个重要概念,它涉及到软件逆向工程,主要用于理解或学习已编译的Java字节码(.class文件)的工作原理。Java的源代码被编译成字节码后,虽然失去了人类可读的形式,但通过反编译工具,我们...

    Java反编译工具jui

    Java反编译是Java开发中一个重要的辅助工具,主要用于查看和理解Java字节码,将已编译的.class文件或.jar文件转换回源代码形式。这在进行逆向工程、学习开源项目、修复bug或者理解未知代码的工作流程时非常有用。...

    java反编译工具 jad

     -nonlb - 不要输出一个新行在打开一个括号之前 (default: do)  -o - 无需确认直接覆盖输出 (default: no)  -p - 发送反编译代码到标准输出 STDOUT (e.g., for piping) 对于很多人说jad反编译后中文显示乱码...

    java.class 反编译工具

    在提供的文件名称列表中,"jd-gui"是一个常见的Java反编译工具。JD-GUI(Java Decompiler GUI)是一个图形界面的应用,它可以显示Java类文件的源代码视图。它不仅支持单独的class文件,还能够直接打开和浏览jar文件...

    java反编译工具 java反编译工具

    - **Procyon**:这是一个开源的Java反编译和编译工具,它提供了比JAD更好的语法还原能力。 - **FernFlower**:另一款开源的Java反编译器,其反编译结果通常比其他工具更接近原始源代码。 - **JDeobfuscator**:...

    java .class反编译成.java工具

    常用的Java反编译工具有jad、FernFlower、Cfr等,而jd-gui.exe是其中一种图形界面的反编译工具,它提供了一个直观的方式来查看和分析.class文件。 jd-gui.exe的使用步骤如下: 1. **下载与安装**:首先,你需要从...

    java编译class文件

    标题“java编译class文件”涉及的核心知识点是Java的编译过程。Java源代码文件的扩展名为`.java`,这些文件包含类定义、方法定义以及其他Java语法元素。要将`.java`文件编译成`.class`文件,我们需要使用Java的JDK...

Global site tag (gtag.js) - Google Analytics