class Chinese
{
static String country ="中国";
static void sing()
{
System.out.println("啊");
singOurCountry();
}
void singOurCountry()
{
System.out.println(country);
sing();
}
}class ChineseDemo
{
public static void main(String [] args)
{
new Chinese().sing();
new Chinese().singOurCountry();
}
}
//singOurCountry()方法中需要打印输出的变量country是一个已经定义了的静态成员变量。静态成员方法sing()为什么不能调用非静态的成员方法singOurCountry()?
//哪位大侠给兄弟指点一下。
//小弟我才学java几天,还是在网上照着视频教程学的。

解决方案 »

  1.   

    你是说System.out.println("啊"); 
    singOurCountry(); 这段代码sing() 方法是静态的,而singOurCountry()方法是非静态的。
    非静态方法可以访问静态方法,静态属性,非静态方法,非静态属性。但是静态方法只能访问静态的方法和静态的属性
      

  2.   

    class Chinese
    {
    static String country ="中国";
    static void sing()
    {
    System.out.println("啊");
    singOurCountry();
    }
    void singOurCountry()
    {
    System.out.println(country);
    sing();
    }
    }class ChineseDemo
    {
    public static void main(String [] args)
    {
    new Chinese().sing();
    new Chinese().singOurCountry();
    }
    } 在一个static 方法中引用任何实例变量和方法都是非法的。
      

  3.   

    我是意思是 我已经通过static String country ="中国"; 定义了一个静态的变量。然后我在使用一个非静态的方法去调用这个已经在内存中存在的静态变量,这样为什么还是不可以?难道是因为非静态的方法只能被已经存在的对象所调用吗?这样的话我在下面已经new了两个新的对象为什么还是不行?即使我吧main函数中的内容换成:
    Chinese ch1 = new Chinese();
    ch1.sing();
    这样也还是不行啊。或者把void singOurCountry() 方法中的变量 country变成this.country 这样给他指定具体的对象也不行 到底是为什么呢?
      

  4.   


    请问,你编译通过了么?问题不在于你那个静态变量的调用。
    singOurCountry方法调用静态变量没问题,问题是你在静态方法static void sing()
    中调用了非静态方法singOurCountry()。
      

  5.   

    你创建的void singOurCountry()的这个方法本身不是一个静态方法 虽然里面调用了静态变量 但方法本身是一个实例方法 然后你在一个静态方法static void sing()里调用singOurCountry(), 这就成为了在一个static 方法中引用实例方法,在编译中,这是java不允许的,一定会报错的。
    除非你把singOurCountry()也定义为静态方法。还是那句话 在一个static 方法中引用任何实例变量和方法都是非法的。
      

  6.   

    引用2楼:在一个static 方法中引用任何实例变量和方法都是非法的。 引用3楼:非静态方法可以访问静态方法,静态属性,非静态方法,非静态属性。但是静态方法只能访问静态的方法和静态的属性告诉我的东西都跟定义一样,我就当定义背下来吧··至于这里所只的非法,我先暂时当做sun公司编写的时候就是这么规定的,以后我在回过头来研究它为什么非法 哈哈哈。
      

  7.   

    稍微说说“静态”与“非静态”到底是什么概念吧。用面向对象的观点:
    所谓“静态”就是“类的东西”(包括变量、常量、方法等);所谓“非静态”就是“对象的东西”或者“实例的东西”。
    那么楼主的问题就变成“一个类方法为什么不能调用一个实例方法呢”。举个例子(也许不太实际),假设有个类叫做“人”,也就是人类(human being),它有个类方法(静态方法)叫做“吃饭”eat(),如果你调用eat(),那么还没有出生的人能不能“吃”呢?当然,这个例子实际上是不合理的,对于“人”这个类,eat()方法不能够是静态的,如果是静态的话,一旦调用,目前所有活着的人都要同时开始吃饭,并且同时吃完,这显然是不符合常理的。例子虽然不合理,但我想应该可以解答楼主的问题了。
      

  8.   


    别死背,要理解,你真正理解了“静态”的意义,就不会写出这种code了。
    这不是sun的规定,而是面向对象思想的合理性决定的。
      

  9.   

    liuxiaosabbbath看到了就加一下我的qq好不,这里打字太慢了qq:5929712
      

  10.   

    static 方法是类方法,相当是全局的
    非static 方法是对象方法,只有具体对象才能调用
    如果你的类里面还一个字段
    String str = "sss" ;//方法改成这样
    void singOurCountry() {
        System.out.println(country);
        System.out.println(this.str);//(2)
        sing();
    }
    这时,你new 了两个chinese1,chinese2对象,并重新给str赋值
    你说该叫static中调用的singOurCountry中的(2)这一行的str是取chinese1的str, 还是取chinese2的str
    这显然是不合理的,所以不会允许静态方法调用非静态的方法
      

  11.   


    抱歉,我人在国外,QQ全乱码无法使用,你如果有MSN可以加我[email protected]
      

  12.   

    我发现很多人喜欢问这个问题!曾经我看过一个的视频  浙江大学 翁凯教授
    我真的深受启发,虽然当时我真的没听明白,但我后来慢慢明白。
    我现在的理解:// static(静态)不属于面向对象范畴,但是在编程中确实又特别方便,所以保留了这个东西。
    用static是以前C语言中的全局变量,但在面向对象中要解释是解释不了的。
    我勉强一点解释吧,如果有一个类叫人类,那么如果有一种东西是全人类都有的那么他就可以用static修饰。
    但因为调用的时候可以不经过实例化就能改变这么个变量,所以这个就脱离了面向对象。其它的暂时没想到。想到了再补吧
      

  13.   

    晕头转向,,真是只可意会不可言传啊。
    怪不得人家都说学java需要很强的抽象思维能力。学到这里我是深有体会了。
    不过看了几位的解释方法,我好像又有一点点头绪,明白了那么一点。
    虽然还没有完完全全的理解不过还是谢谢各位,我去用15楼的代码在去练习一会仔细体会下。
      

  14.   


    因为这两个不是出问题的原因,出问题的原因在于静态方法中非法的调用了非静态方法
    把sing()方法前面的修饰符static拿掉就可以通过编译了
    即便如此,运行这段代码,最终会导致栈内存溢出StackOverflowError
      

  15.   

    也许可以试着先记住这么用就好了。再以后的学习中就会慢慢理解了。现在对于JAVA了解的还少。
      

  16.   


    呵呵,其实这个东西也是可以解释清楚的,只是解释起来比较费力,涉及到编译期和运行期的知识,所以很多人只能意会不能言传,如果想深刻的理解这个问题,建议去请教ZangXT大侠~
      

  17.   


    我做的是结果 2楼说的是为什么 这个和编译器在编译时的内存分配有关
    举个例子 
    我们把编译看成一个产品的生产,方法是产品的工序,变量是产品的原材料 
    静态方法和变量相当于在这个产品的生产过程中是最先的工序和最初的原材料,而实例变量和方法是后面的工序
    因为编译器在编译时会在内存中最先把静态变量和方法编译出来
    而在你的产品生产(程序编译)中,先生产static void sing()这个静态工序,在这个工序中,她用到了void singOurCountry() 这道工序所生产的出来的原材料。而此时void singOurCountry() 这道工序还没有开始生产。这里整个生产就出现了问题。
      

  18.   

    在问一下 ZangXT大侠 是谁?
      

  19.   

    从面向对象来说.普遍来说静态是对于类而言,非静态是对于类的对象来说的.可以说,对于类来说,他的对象他不知道怎么处理的.而对于对象来说.他知道他的类是什么情况.俗一点来说.人类有一个大脑.但是人类也不知道你,我,他有什么东东,他只知道对于人类来说,就是一个大脑,只知道他自己的情况.相反你,我,他都知道人类有一个大脑.再来说,如果静态要调用非静态的,那只能说,你的思考方法就有问题.因为静态方法是对于类来说的,调用非静态方法,简单来说,你要好知道他的对象的情况.而这在面向对象是不可能的.如你想一下.人类知道,你的情况,我的情况,他的情况吗,不知道,他只知道他自己的情况.说了这么多,不知你理解没,说一下,你思考一下为什么C#重载运算符为什么要用静态的.常用string类的Compare,IsNullOrEmpty,wstrcpy方法为静态.还有属性Empty为什么是静态的.
    以上是个人理解,仅供参考.