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几天,还是在网上照着视频教程学的。
{
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几天,还是在网上照着视频教程学的。
singOurCountry(); 这段代码sing() 方法是静态的,而singOurCountry()方法是非静态的。
非静态方法可以访问静态方法,静态属性,非静态方法,非静态属性。但是静态方法只能访问静态的方法和静态的属性
{
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 方法中引用任何实例变量和方法都是非法的。
Chinese ch1 = new Chinese();
ch1.sing();
这样也还是不行啊。或者把void singOurCountry() 方法中的变量 country变成this.country 这样给他指定具体的对象也不行 到底是为什么呢?
请问,你编译通过了么?问题不在于你那个静态变量的调用。
singOurCountry方法调用静态变量没问题,问题是你在静态方法static void sing()
中调用了非静态方法singOurCountry()。
除非你把singOurCountry()也定义为静态方法。还是那句话 在一个static 方法中引用任何实例变量和方法都是非法的。
所谓“静态”就是“类的东西”(包括变量、常量、方法等);所谓“非静态”就是“对象的东西”或者“实例的东西”。
那么楼主的问题就变成“一个类方法为什么不能调用一个实例方法呢”。举个例子(也许不太实际),假设有个类叫做“人”,也就是人类(human being),它有个类方法(静态方法)叫做“吃饭”eat(),如果你调用eat(),那么还没有出生的人能不能“吃”呢?当然,这个例子实际上是不合理的,对于“人”这个类,eat()方法不能够是静态的,如果是静态的话,一旦调用,目前所有活着的人都要同时开始吃饭,并且同时吃完,这显然是不符合常理的。例子虽然不合理,但我想应该可以解答楼主的问题了。
别死背,要理解,你真正理解了“静态”的意义,就不会写出这种code了。
这不是sun的规定,而是面向对象思想的合理性决定的。
非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
这显然是不合理的,所以不会允许静态方法调用非静态的方法
抱歉,我人在国外,QQ全乱码无法使用,你如果有MSN可以加我[email protected]
我真的深受启发,虽然当时我真的没听明白,但我后来慢慢明白。
我现在的理解:// static(静态)不属于面向对象范畴,但是在编程中确实又特别方便,所以保留了这个东西。
用static是以前C语言中的全局变量,但在面向对象中要解释是解释不了的。
我勉强一点解释吧,如果有一个类叫人类,那么如果有一种东西是全人类都有的那么他就可以用static修饰。
但因为调用的时候可以不经过实例化就能改变这么个变量,所以这个就脱离了面向对象。其它的暂时没想到。想到了再补吧
怪不得人家都说学java需要很强的抽象思维能力。学到这里我是深有体会了。
不过看了几位的解释方法,我好像又有一点点头绪,明白了那么一点。
虽然还没有完完全全的理解不过还是谢谢各位,我去用15楼的代码在去练习一会仔细体会下。
因为这两个不是出问题的原因,出问题的原因在于静态方法中非法的调用了非静态方法
把sing()方法前面的修饰符static拿掉就可以通过编译了
即便如此,运行这段代码,最终会导致栈内存溢出StackOverflowError
呵呵,其实这个东西也是可以解释清楚的,只是解释起来比较费力,涉及到编译期和运行期的知识,所以很多人只能意会不能言传,如果想深刻的理解这个问题,建议去请教ZangXT大侠~
我做的是结果 2楼说的是为什么 这个和编译器在编译时的内存分配有关
举个例子
我们把编译看成一个产品的生产,方法是产品的工序,变量是产品的原材料
静态方法和变量相当于在这个产品的生产过程中是最先的工序和最初的原材料,而实例变量和方法是后面的工序
因为编译器在编译时会在内存中最先把静态变量和方法编译出来
而在你的产品生产(程序编译)中,先生产static void sing()这个静态工序,在这个工序中,她用到了void singOurCountry() 这道工序所生产的出来的原材料。而此时void singOurCountry() 这道工序还没有开始生产。这里整个生产就出现了问题。
以上是个人理解,仅供参考.