本来我对static没有疑问,但是看了Thinking in java中5.4.2节中有这样一个话“在static方法的内部不能调用非静态方法”,这也没什么疑问,但是这句话有个注释:
“这不是完全不可能。如果你传递一个对象的引用到静态方法里(静态方法可以创建其自身对象),然后通过这个引用(和this效果相同),你就可以调用非静态方法和访问非静态数据成员了。”
请各位大牛为小弟解惑啊,如果能编个实际的例子说明注释的问题就更好了,小弟先拜谢了!!
NoStatic 方法
[code="java"]public class NoStatic {
public void outPut(){
System.out.println("非静态输出");
}
}[/code]
这个是主类,test方法是static静态方法,调用了outPut的非静态的方法。
传递一个对象的引用,这里将NoStatic 的引用作为参数传递到test
[code="java"]public class Static {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
NoStatic ns =new NoStatic();
Static.test(ns);
}
public static void test(NoStatic ns){
ns.outPut();
}
}
[/code]
static静态方法不能直接调用本身的非静态方法
“这不是完全不可能。如果[color=red]你传递一个对象的引用到静态方法里[/color](静态方法可以创建其自身对象),然后通过这个引用(和this效果相同),你就可以调用非静态方法和访问非静态数据成员了。”
注意红色部分的意思,相当于是传递外面的对象引用到静态方法里了,那在静态方法也就是一个局部变量的概念了,局部变量当然可以在方法内部访问了
传了引用进去了,当然可以调用了
public class Test {
//这是一个静态方法
public static void main(String[] args) {
//传入一个对象的引用
Test demo = new Test();
//调用非静态方法
demo.test();
}
public void test() {
System.out.println("非静态方法");
}
}
[code="java"]
public class Test{
/**非静态私有数据域*/
private int i=0;
/**静态方法*/
public static void test(Test t){
// System.out.println(i); //编译错误
System.out.println(t.i); //编译通过
}
}[/code]
静态方法中是不允许出现this关键字的,这一点也就说明了静态方法属于类而不属于对象。
但是方法中调用其他对象中的成员毫无疑问是没有问题的。上面的代码 System.out.println(t.i);中的t是另外创建的Test对象,而不是自己this
顶1楼 Rowen (资深程序员) 2009-11-24
就是直接把一个类A做为参数传递给一个静态方法,这样这个静态方法就能调用那个A类里面的所有东西了,不管是静态还是非静态的,方法和变量都可以,在开发中也常用..
注意,所谓的静态方法内部不能调用非静态方法和字段,是因为,一个类会有很多实例对象,每个实例对象的非静态属性都可能是不一样的,类的非静态方法与类的某个实例对象绑定的起来才有意义。你想想,假如类A有个静态方法b()和非静态方法c(),非静态的实例变量s,c()方法的作用是输出s的值,那么现在你若在b()中调用c()方法,由于c()方法中的s的值是与A对象的某个实例挂钩的,不同的A对象,其s值不一样,由于你并未实例化A对象(A.b()调用b方法),你这样调用,java就不知道没法找到s的值。
但“你传递一个对象的引用到静态方法里静态方法可以创建其自身对象”,在b方法中调用c的时候,c已经与具体的实例对象绑定了,就能正确执行。
总结:所谓的静态方法内部不能调用非静态方法和字段,本质在于非静态方法找不到与之对应的实例对象(没有初始化),如果你手动为非静态方法绑定某一具体实例,那在静态方法内部还是可以调用非静态方法和字段的。