JUST DO IT ~

我只想当个程序员

一个 Generic问题

一个 Generic问题 
来自 http://blog.csdn.net/zhangxiaoxiang/archive/2006/11/07/1372076.aspx?Pending=true

下面程序的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(); 
*/

   
 }

}
 


我把这段程序调试了一下


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(); 
*/


           
         Class 
< ? extends Test> c = ((Test)obj).getClass();
         
//因为Generic, 编译器可以在编译期获得类型信息所以可以编译这类代码。你将下面那两行改成 

           c.newInstance().func(); 
   
 }

}
 







下面的代码
   Object obj = new Test();

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


javap之后

public static void main(java.lang.String[])   throws java.lang.Exception;
  Code:
   0:   new     #5; //class Test
   3:   dup
   4:   invokespecial   #6; //Method "<init>":()V
   7:   astore_1
   8:   aload_1
   9:   checkcast       #5; //class Test
   12:  invokevirtual   #7; //Method java/lang/Object.getClass:()Ljava/lang/Class;
   15:  invokevirtual   #8; //Method java/lang/Class.newInstance:()Ljava/lang/Object;
   18:  checkcast       #5; //class Test
   21:  invokevirtual   #9; //Method func:()V
   24:  return

}
   

    ((Test)c.newInstance()).func();


   52:  invokevirtual   #16; //Method java/lang/Class.newInstance:()Ljava/lang/Object;
   55:  checkcast       #5; //class Test



virtualf 发表于2006-11-08 14:19:00  IP: 222.209.220.*

这是编译器行为.

((Test)obj).getClass().newInstance().func();

<=>

((Test)(obj.getClass().newInstance())).func();


可以反编译后查看.

//的确如此。




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

  
  
   9:   checkcast       #5; //class Test
   12:  invokevirtual   #7; //Method java/lang/Object.getClass:()Ljava/lang/Class;
   15:  astore_2
   16:  aload_2
   17:  invokevirtual   #8; //Method java/lang/Class.newInstance:()Ljava/lang/Object;
   20:  checkcast       #5; //class Test
   23:  invokevirtual   #9; //Method func:()V
   26:  return

}

  Class < ? extends Test> c = ((Test)obj).getClass();
  System.out.println(); 
  Test  ff=  c.newInstance();//.func();

就无需转换 .直接拿到对象了.

 

getClass

public final Class<? extends Object> getClass()






当系统认为 class 变量 < 来自那个类的class >
通过 class 变量.newInstance; 被赋予了 那个类的类型.

posted on 2006-11-08 16:16 小高 阅读(261) 评论(0)  编辑  收藏 所属分类: java基础


只有注册用户登录后才能发表评论。


网站导航:
 

导航

<2006年11月>
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789

统计

常用链接

留言簿(3)

随笔分类(352)

收藏夹(19)

关注的blog

手册

搜索

积分与排名

最新评论

阅读排行榜

评论排行榜