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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 尘埃落定 中级黑马   /  2014-7-24 11:16  /  9680 人查看  /  14 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

如下代码:
Test9.Inner9.method();这样写无法运行,是说明匿名内部类不能用静态修饰么?

  1. interface Inter9
  2. {
  3.         void method();
  4. }

  5. class Test9
  6. {
  7.         static new Inner9()
  8.         {
  9.                 public static void method()
  10.                 {
  11.                         System.out.println("method run");
  12.                 }       
  13.         }
  14. }

  15. class  InnerClassTest9
  16. {
  17.         public static void main(String[] args)
  18.         {
  19.                 Test9.Inner9.method();
  20.         }
  21. }

复制代码


14 个回复

倒序浏览
本帖最后由 chen010yu 于 2014-7-24 13:41 编辑

111111111111111111
回复 使用道具 举报
因为系统在创建匿名内部类的时候,会立即创建匿名内部类的对象。
回复 使用道具 举报
FireWater 发表于 2014-7-24 14:04
因为系统在创建匿名内部类的时候,会立即创建匿名内部类的对象。

能详细点么?不是很理解你的意思
回复 使用道具 举报
本帖最后由 chen010yu 于 2014-7-24 14:31 编辑

匿名内部类只能定义在方法内部,他本身是一种特殊的局部内部类,您的匿名内部类定义的位置有误,匿名内部类其实就是通过“new 父类(){};”语句来实现的,没有名字,不可以用"类名."方式调用其中的方法,如果想用这种方法调用类中的方法,就必须得给他起个名字,他不能被static修饰,因为他不是类成员;例如你的代码中
      Inter9 in = new Inter9()
      {
          public void method()
          {
             System.out.println("method run");
          }
      };
      in.method(); // 这样只能调用父类原有的方法
否则只能这样调用:
new Inter9()
{
   public void method()   {
       System.out.println("method run");
   }
}.method();

希望能帮助到你.
回复 使用道具 举报 1 0
首先,你这里有几个错误。
第一,Inter9是接口,接口是无法直接实例化的;
第二,接口中不能有static修饰的方法;
第三,匿名内部类中的方法,其实是重写的父类方法或者实现的接口方法,那么就必须与父类或者接口中的方法一致,就和第二条一样,接口中不能有static修饰的方法.而且static不支持继承,因为他和对象无关,更不存在重写这一说法
第四,匿名内部类适合那种只需要实例化一次的对象,不存在复用之说;,static是用来修饰成员变量和成员方法的,而匿名内部类没有变量名,所以根本不能作为成员变量存在,更不要说使用static修饰了
回复 使用道具 举报 2 0
查了资料:
1.匿名内部类不能定义任何静态成员、方法和类。
2.匿名内部类不能是public,protected,private,static。
果然匿名内部类不能用static修饰。
当初还琢磨匿名内部类因为没有类名,应该不能用“类名.”的方式,所以,应该不能静态。
只是不确定,虽然代码显示无法运行成功,还是希望得到一个确切的答案。
现在已有明确的资料显示,只能告诉自己的脑袋记住。
回复 使用道具 举报 1 0
interface Inner9
{
        public abstract void method();
}

public class  Practise01
{
        public static void main(String[] args)
        {
                new Inner9()
                {
                        public void method()
                        {
                                System.out.println("method run");
                        }        
                }.method();
        
                System.out.println("HelloWorld!");
        }  
}
照这样写运行就成功了。
回复 使用道具 举报
尘埃落定 发表于 2014-7-24 22:14
查了资料:
1.匿名内部类不能定义任何静态成员、方法和类。
2.匿名内部类不能是public,protected,private,s ...

匿名内部类是一种特殊的局部内部类,局部成员,是不能用public、protected、private、static修饰的,自然局部成员内部也不能有。
回复 使用道具 举报
{:2_30:}{:2_30:}{:2_30:}{:2_30:}{:2_30:}{:2_30:}
回复 使用道具 举报
chen010yu 发表于 2014-7-24 22:42
interface Inner9
{
        public abstract void method();

谢谢,
知道这种写法,所以想尝试下静态
回复 使用道具 举报
本帖最后由 zeus00456 于 2014-7-28 14:34 编辑

lz你看我的说法,和楼上的各位哪个好接受你就接受哪个吧。

首先,澄清最关键的一点——匿名内部类虽然叫做匿名内部类,但是他的本质是一个匿名内部类的对象,是的,它的本质是对象(因为匿名内部类是new出来的,new出来的东西是个对象啊)!
其次,匿名内部类在外部类的里面(废话)
由上面可知,匿名内部类在外部类中的一个对象,其地位等同于一个成员变量
更具体的讲,请看下面代码
class Outer
{
Integer a=new Integer(123);//这是一个整型对象,一个外部类中的Integer类型的成员变量
new XXX(){/*内容我就不写了*/};//这是一个匿名内部类,本质是一个对象,它其实也是一个成员变量
}
我们来比较一下,
首先,一个类中只有三个部分:构造方法、成员方法、成员变量
上面的两个玩意肯定不是构造方法吧
也不是成员方法吧,匿名内部类不是一个方法啊,它虽然有{}但是它也不是一个方法,人家是用“;”结尾的
你现在看看
Integer a=new Integer(123);和  new XXX(){};这两个挺像吧
你再看看
new Integer(123)【注意没有前面的"Integer a ="】;和  new XXX(){};这两个是不是更像!
Integer a = new Integer(123);就是一个成员变量,匿名内部类和他类似吧

为啥说是类似呢?
注意区别,人家Integer a=new Integer(123);是有名字的,叫做a
人家可以加static,加了静态后的东西是可以通过  类名.变量名(也叫字段 field)的形式调用
上面的Integer加静态后变成了  static Integer a = new Integer(123);
后面你就可以用 Outer.a 调用了

匿名内部类行吗?
假设它可以,来,咱调用一次
类名咱有,Outer,匿名内部类(对象)的名字呢?你别忘了你是匿名的,调用不了。
所以,这就解释了匿名内部类为什么不能加静态

总结一下,
1,匿名内部类本质是定义在外部类中的一个对象,地位等同于外部类中的成员变量
2,它和一般的成员变量是不同的,它因为是匿名对象,没有名字,准确的讲,没有变量名
3,对于一般的成员变量,如果加了静态,就意味着可以在其他地方,不建立外部类的对象,通过
外部类名.成员变量名  的方式进行直接调用
4,匿名内部类(对象)不行,因为它没有成员变量名

超级总结一下,匿名内部类不能加静态,归根到底就是因为:它是一个匿名成员变量,加了静态后无法用变量名调用<真是悲催的娃啊>。
回复 使用道具 举报
zeus00456 发表于 2014-7-28 14:32
lz你看我的说法,和楼上的各位哪个好接受你就接受哪个吧。

首先,澄清最关键的一点——匿名内部类虽然叫做 ...

精辟,讲的很深刻,受教
回复 使用道具 举报
看你们说那么多 还有楼主你的那个可以调用
回复 使用道具 举报
class Son
{
        void say(){Son2 s=new Son2();}
        static class Son2
        {
                static void say(){System.out.println("内部类的方法");}
               
        }

}
class Demo
{
        public static void main(String[]ages)
        {
                Son.Son2.say();
        }

}






试试上面的代码,你的那个是有名字的内部类 不是匿名
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马