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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© Tesla时光 中级黑马   /  2012-9-9 23:40  /  1732 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 翁发达 于 2012-9-10 21:01 编辑

静态方法中不可以用super,这个结果我知道,但我想知道具体原因是什么?
这里我的成员变量都静态了,super代表父类的引用,引用的是一个静态变量,按理说是可以的.
麻烦帮解答下,尽量详细点.谢谢
public class A
{   
        static int x = 1;
        public void show()
        {
                System.out.println(x);
        }
}
class B extends A
{
        static int x = 2;
        public static void print()
        {
                        super.x = 3;
                        System.out.println(super.x);
        }
}

6 个回复

正序浏览
1.super的用法跟this类似,this代表对本类对象的引用,指向本类已经创建的对象;而super代表对父类对象的引用,指向父类对象;
2.静态优先于对象存在;
3.由上面的1.和2.知:
因为静态优先于对象存在,所以方法被静态修饰之后方法先存在,而方法里面要用到super指向的父类对象,但是所需的父类引用对象晚于该方法出现,也就是super所指向的对象没有,当然就会出错。
综上,静态方法中不可以出现super关键字。
回复 使用道具 举报
就用你的代码这么跟你说吧

首先,通常定义对象都是B b = new B();这个可以分解为 B b;b = new B();
假设可以在静态方法中super.x = 3;这样调用,而这次我们先不给b实例化,先定义一个B b;这个时候B类进入了内存空间,而在堆内存中还没有B的实体,但是在方法区已经有了print()方法,可以直接通过B.print()调用该静态方法,但是你的方法里面如果有了super.x = 3;,这个时候,B类还没有实例化,所以方法区,还没有A类,自然也就没有A中的静态的x

其实这样就算编译设器在计的时候不管这个问题,可是在运行的时候类中的静态是最优先加载的,有了类就有了静态,所以print()一存进内存,super这东西虚拟机就不认识了,自然得玩玩,

这么说你应该懂了吧
回复 使用道具 举报
在这里首先纠正LZ在一个文件中只能有一个类被public修饰,而且修饰的类名要与文件名一致。
再说“super”和“static”,由static修饰的成员变量和方法,都是在类加载时而加载的,所以就是不管你的类是否实例,它们已经存在了,所以可以通过“类名.方法”和“类名.变量”使用,通过对象调用,可是当static修饰的成员变量和方法存在时,对象不一定存在,super就是父类的一个引用,这时内存中还不存在“super”这个引用,所以静态方法中不能存在“super”
回复 使用道具 举报
1:子类创建对象的时候,会默认调用父类的无参构造。
  因为每个构造方法,第一行都默认有一个super()去调用父类的无参数构造。
  
  不管是java提供给我们使用的类,还是我们自定义的类都直接或者间接的继承Object类。
  Object是类层次的根类。

  为什么子类的构造方法中都有默认的super,是因为子类继承父类的时候,需要由父类去明确对
  父类中数据的初始化。
2:假如父类没有无参构造。
子类的构造方法必须通过this或者super语句指定要访问的构造方法。

super关键字:代表父类空间的引用。

this():调用本类的构造方法
super():调用父类的构造方法
*/
class Fu //extends Object
{
        /*
        Fu()
        {
                //super();
                System.out.println("Fu()");
        }
        */

        Fu(int num)
        {
                System.out.println("Fu(int num):"+num);
        }
}

class Zi extends Fu
{
        Zi()
        {
                //super();
                //super(10);
                this(10);
                System.out.println("Zi()");
        }

        Zi(int num)
        {
                //super();
                super(num);
                System.out.println("Zi(int num):"+num);
        }
}

class ExtendsDemo3
{
        public static void main(String[] args)
        {
                //单独调用父类
                //Fu f = new Fu();
                //Fu f2 = new Fu(20);

                Zi z = new Zi();
                Zi z2 = new Zi(20);
        }
}
回复 使用道具 举报
super是创建对象之后才能使用的,而static是在对象创建之前就存在的,所以static方法进入内存的时候super是不存在的,当然会产生编译错误。

public class A
{   
        static int x = 1;
        public void show()
        {
                System.out.println(x);
        }
}
public class B extends A
{
        static int x = 2;
        public static void print()//static方法进入内存,此时对象还没有产生,即内存中没有super,故无法使用。
        {
                        super.x = 3;
                        System.out.println(super.x);
        }
}
回复 使用道具 举报
super代表的是对父类对象的引用,指向父类对象;而静态优先于对象存在,因此静态方法中不可以用super
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马