学员冯伟立今天中午问了我一个有趣的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:00  IP: 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

转载于:https://www.cnblogs.com/javaEEspring/archive/2006/11/07/2522978.html

一个有趣的Java编译问题相关推荐

  1. 使用Java编一个有意思的_一个有趣的Java编译问题

    学员冯伟立今天中午问了我一个有趣的Java编译问题,我也无法给他解释,不知道有没有路过的高人能够解释清楚原因,望不吝赐教! 下面程序的main方法中的第二行代码和注释中的两行代码表达的意思完全相同,注 ...

  2. java的linux内核构建,构建一个Docker 的Java编译环境

    用Dockerfile 构建一个Java的编译环境 1.包括以下软件包 Ubuntu jdk maven svn 2.jdk.maven 需要手动下载,下载之后分别为 jdk-8u51-linux-x ...

  3. 记一个有趣的Java OOM!

    2019独角兽企业重金招聘Python工程师标准>>> 本文首发于个人微信公众号<andyqian>,期待你的关注- 引言 熟悉Java的童鞋,应该对OOM比较熟悉.该类 ...

  4. 3. 自定义Java编译时注解处理器

    1. 絮絮叨叨 要么是注解跟我有仇,要么是公司配发的笔记本跟我有仇,要么是因为心急吃不了热豆腐 痛定思痛:从头开始,新建一个Java项目,实现一个超级简单的注解@Hello 通过获取被标识类的类名(原 ...

  5. 这是一个有趣的问题,Java 8 Lambda 表达式被编译成了什么?

    在了解了Java 8 Lambda的一些基本概念和应用后, 我们会有这样的一个问题: Lambda表达式被编译成了什么? 这是一个有趣的问题,涉及到JDK的具体的实现.本文将介绍OpenJDK对Lam ...

  6. Apache Software Foundation Thinking in Java:构造器调用的层次结构带来了一个有趣的两难问题

    引论 : 构造器调用的层次结构带来了一个有趣的两难问题.如果在一个构造器的内部,同时调用正在构造的那个对象的某个动态绑定方法,那会发生什么情况呢?在一般的方法内部,我们可以想象会发生什么:动态绑定的调 ...

  7. 【Java 28岁了】一个有趣的例子,再推荐一些经典好书(文末惊喜福利)

    文章目录 1 写在前面 2 C语言与Java语言的互相调用 2.1 C语言调用Java语言 2.2 Java语言调用C语言 3 友情推荐 4 更多分享 1 写在前面 众所周知,C语言和Java语言是两 ...

  8. 程序员心中都有一个江湖,java世界,就是一个江湖!

    大千世界,无所不有.这世上不光有人类世界,还有咱们的 java 世界.今天就由我这个实习导游带领你们了解了解咱们的 java 世界的奇妙之处. 有一种暖男叫 catch,有一种真爱叫 try---ca ...

  9. Quarkus:一个Kubernetes原生Java框架

    Red Hat发布了Quarkus,这是一个为GraalVM和OpenJDK HotSpot量身定制的Kubernetes原生Java框架.Quarkus的目标是使Java成为Kubernetes和无 ...

  10. 怒肝俩月,新鲜出炉史上最有趣的Java小白手册,第一版,每个 Java 初学者都应该收藏

    这么说吧,在我眼里,Java 就是最流行的编程语言,没有之一(PHP 往一边站).不仅岗位多,容易找到工作,关键是薪资水平也到位,不学 Java 亏得慌,对吧? 那可能零基础学编程的小伙伴就会头疼了, ...

最新文章

  1. 皮一皮:防狼泳衣...
  2. 1.11 抽象(abstract)类
  3. SGU 117 Counting
  4. python面向对象难学_python-面向对象进阶
  5. springboot+Druid+mybatis整合
  6. testlink界面优化_Testlink 太老了,测试用例管理有没有什么好工具推荐?
  7. 认识以及安装redis
  8. 多个select 多个列_程序员,你还在 Select * 吗?
  9. dependencyManagement 失效
  10. linux同时连接内外网的设置
  11. vue和js点击下载pdf,word,png,jpg等格式的文件,解决点击下载pdf却是打开预览的问题
  12. 什么时候需要用到RCC_APB2Periph_AFIO
  13. so easy! 10行代码写个狗屁不通文章生成器
  14. FFMPEG AvFilter使用实例(实现视频缩放,裁剪,水印等)
  15. 怎么在韩国VPS服务器与虚拟主机中进行选择?
  16. python求满足条件的值的个数_计算列表中满足特定条件的值的数目
  17. python课程设计编写电子通讯录_python写一个通讯录
  18. 随机点名小程序 tkinter
  19. 【项目相关技术】前端由来、vscode安装使用、ECMAScript 6、Vue、element-ui、Node.js、npm、模块化、WebPack
  20. 企业采购季选好开发板平台 迅为4418开发板

热门文章

  1. 计算机组成原理完整学习笔记(二):系统总线
  2. 美图欣赏,转载[原文链接http://toutiao.com/a4001258776/]
  3. Spring boot Redis客户端 乱码
  4. Docker在centos下安装以及常见错误解决
  5. CSS设置一行文字,超出部分自动隐藏
  6. sql server利用开窗函数over() 进行分组统计
  7. 微软小冰你这么智能 .net知道吗?
  8. 云计算相关的一些概念Baas、Saas、Iaas、Paas
  9. 利用设计模式优化项目实际的申报业务
  10. mysql日常工作中批量插入效率问题