A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© kid1943 中级黑马   /  2014-10-21 10:15  /  2497 人查看  /  22 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

今天看到一代码,该代码实例化了一个内部类,但却不用先实例化其外部类。于是感到奇怪,因为以前实例化内部类都是需要类似的格式:
  1. Outclass.Innerclass ic=new Outclass.new Innerclass();
复制代码
但外部类想实例化静态内部类却不能这么写:
  1. package com.kid.innerclass;

  2. import com.kid.innerclass.Outclass.Innerclass;

  3. public class Outclass {

  4.         public static class Innerclass {

  5.                 Innerclass() {

  6.                         System.out.println("Innerclass is comming");
  7.                 }
  8.         }
  9. }

  10. class Test1 {

  11.         public static void main(String args[]) {
  12.                 Innerclass ic = new Innerclass();
  13.                 Outclass.Innerclass ic2 = new Outclass.Innerclass();
  14.                 Innerclass ic3 = new Outclass.Innerclass();

  15.                 /*
  16.                  * Innerclass ic4=new Outclass().new Innerclass();//这种写法错误
  17.                  */      
  18.         }

  19. }
复制代码

问题来了,为什么不可以这么写:
  1. Outclass.Innerclass ic=new Outclass.new Innerclass();
复制代码
它和程序上其他三种写法有何区别呢?




评分

参与人数 1技术分 +1 收起 理由
杨佳名 + 1 赞一个!

查看全部评分

22 个回复

倒序浏览
话说有24行的那种写法吗
回复 使用道具 举报
HM2014nuli 发表于 2014-10-21 10:19
话说有24行的那种写法吗

有啊 不过前提是你的内部类是非静态 你可以测试一下看看
回复 使用道具 举报
kid1943 发表于 2014-10-21 10:20
有啊 不过前提是你的内部类是非静态 你可以测试一下看看

19和21都是错的吧
回复 使用道具 举报
这就要搞清静态了,静态方法的调用,是不需要建立对象直接用类名调用的,因为一加载类,静态就存在了,那么静态内部类也是在外部类的成员位置上,也就不需建立外部类对象再调用内部类对象了
回复 使用道具 举报
不知道是不是我的myeclipse有问题,这个代码里第5、19、21行也是错的。第5行Outclass这个类不能用public修饰。而Innerclass这个类根本就不存在,怎么可以直接用它来声明呢?
回复 使用道具 举报
kid1943 中级黑马 2014-10-21 16:58:50
7#

可能是jdk版本问题,我写这段代码是没错误的
回复 使用道具 举报
kid1943 中级黑马 2014-10-21 17:00:56
8#
mingtianrsm 发表于 2014-10-21 14:42
不知道是不是我的myeclipse有问题,这个代码里第5、19、21行也是错的。第5行Outclass这个类不能用public修 ...

那就奇怪了 我在eclipse写是没问题的 我的是jdk7 不知道是不是jdk版本问题
回复 使用道具 举报
kid1943 发表于 2014-10-21 17:00
那就奇怪了 我在eclipse写是没问题的 我的是jdk7 不知道是不是jdk版本问题

不会吧?:o我也是jdk7的啊!明显没有定义Innerclass这个类,咋会没错呢?
回复 使用道具 举报
本帖最后由 cs8630323 于 2014-10-22 13:11 编辑
mingtianrsm 发表于 2014-10-21 20:32
不会吧?我也是jdk7的啊!明显没有定义Innerclass这个类,咋会没错呢?

已删..........................
回复 使用道具 举报
感觉是你导入的类和静态内部类混淆了
回复 使用道具 举报
kid1943 发表于 2014-10-21 17:00
那就奇怪了 我在eclipse写是没问题的 我的是jdk7 不知道是不是jdk版本问题

哦,发现了,你用静态导入了。我把导入那里删掉了
回复 使用道具 举报
首先先解答下前面有人认为以下两行代码错误
  1. Innerclass ic = new Innerclass();
  2. Innerclass ic3 = new Outclass.Innerclass();
复制代码
这两行代码没有错误因为前面有导入内部类
  1. import com.kid.innerclass.Outclass.Innerclass;
复制代码

我用了下eclipse看了下,说实话我很怀疑这种写法的正确性,请贴出具体来源是从哪里看的,然后你看到的代码有验证过吗?
  1. Outclass.Innerclass ic= new Outclass.new Innerclass();
复制代码
这种写法编译器就通不过,我是这么理解的 new 后面跟的是构造函数 new Outclass.new Innerclass();第一个new 后面是什么?无法理解。那么还有一种写法,两个new正确呢?new Outclass().new Innerclass()是因为内部类非静态只有当外部类实例化后才能创建内部类对象。本质上是对象调用对象中的成员。只不过这个成员比较特殊是内部类的构造函数。
然后让我有疑问的问题就产生了为什么下面这个代码是错误的

  1. Innerclass ic=new Outclass().new Innerclass();
复制代码

照理说成员是静态的直接用类名调用是可以的,那么创建对象再调用那就更加没问题了。我试验了下在Outclass类中添加了静态成员变量
  1. public static int num = 5;
复制代码
然后创建外部类对象调用num没有问题为什么 Innerclass ic=new Outclass().new Innerclass();这个形式错了呢?
源码如下,望高手指教  以下代码用的是junit测试的
  1. package com.kid.innerclass;

  2. public class Outclass {
  3.        
  4.                 public static int num = 5;
  5.         public static class Innerclass {

  6.                 Innerclass() {

  7.                         System.out.println("Innerclass is comming");
  8.                 }
  9.         }
  10. }
复制代码
  1. package com.kid.innerclass;

  2. import org.junit.Test;

  3. import com.kid.innerclass.Outclass.Innerclass;


  4. public class Test1 {

  5.            @Test
  6.       public void tt() {
  7.                               int num = new Outclass().num;
  8.                               System.out.println("num----->"+num);
  9.                Innerclass ic1 = new Innerclass();
  10.                Outclass.Innerclass ic2 = new Outclass.Innerclass();
  11.                Innerclass ic3 = new Outclass.Innerclass();
  12.                
  13.              //  Outclass.Innerclass ic4= new Outclass.new Innerclass();

  14.               
  15.                         //Innerclass ic5=new Outclass().new Innerclass();//为什么这种写法错误??
  16.                      
  17.        }

  18. }
复制代码






评分

参与人数 1技术分 +1 收起 理由
杨佳名 + 1 很给力!

查看全部评分

回复 使用道具 举报
cvnmklop 发表于 2014-10-22 18:51
首先先解答下前面有人认为以下两行代码错误
这两行代码没有错误因为前面有导入内部类
我用了下eclipse看了 ...
  1. Outclass.Innerclass ic= new Outclass.new Innerclass();
复制代码

我 忘加括号了应该是
  1. Outclass.Innerclass ic= new Outclass().new Innerclass();
复制代码
回复 使用道具 举报
你定义的是静态内部类。Outclass.Innerclass ic=Outclass.new Innerclass();应该这样
回复 使用道具 举报
kid1943 发表于 2014-10-28 08:08
我 忘加括号了应该是

这种写法是非静态内部类
回复 使用道具 举报
cvnmklop 发表于 2014-10-22 18:51
首先先解答下前面有人认为以下两行代码错误
这两行代码没有错误因为前面有导入内部类
我用了下eclipse看了 ...

因为内部类是静态的,不能直接new内部类,相当于不能在静态方法中使用this一样的道理
回复 使用道具 举报
嘿~~ 发表于 2014-10-28 11:05
你定义的是静态内部类。Outclass.Innerclass ic=Outclass.new Innerclass();应该这样

没有这种写法,如果不导入静态内部类要OuterClass.Innerclass ic2 = new OuterClass.Innerclass();
回复 使用道具 举报 1 0
你这里相当于导入了一个静态的成员,就如同导入静态方法一样,类名可以省略,只用在有同样方法的时候才要写类名表明调用的是哪个对象中的方法,所以前三种都是这种情况,外部类可以省略,写法四你是创建了外部类名.内部类名这样一个对象,你只用内部类接收,肯定是错的啊
回复 使用道具 举报
  1. Innerclass ic4=new Outclass().new Innerclass();//这种写法错误
复制代码

前面的正确是可行的,静态内部类不依存于对象。
最后一种错误,我认为是受了对象可以调用静态成员的影响,你认为那是正确的。
我的想法是:本来静态成员变量,静态方法的调用也不应该使用对象进行调用的,但是那样用的人多了,所以sun做了优化,可以通过对象进行调用,但编译器应该会自动将其处理为类的调用。
而静态内部类,本来就用的很少,通过对象去调用静态成员成员本来应该是错误的。静态类也可以看做静态成员,但是sun公司并未做优化。所以是错误的。
对象调用静态成员,方法本来就只是一个迁就习惯的解决方式。

评分

参与人数 1技术分 +1 收起 理由
杨佳名 + 1 赞一个!

查看全部评分

回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 加入黑马