java中静态方法中为什么不能使用this、super和直接调用非静态方法

来源:360DOC 责任编辑:李利平
默认
特大
宋体
黑体
雅黑
楷体


java中静态方法中为什么不能使用this、super和直接调用非静态方法(图2)


java中静态方法中为什么不能使用this、super和直接调用非静态方法(图5)


java中静态方法中为什么不能使用this、super和直接调用非静态方法(图7)


java中静态方法中为什么不能使用this、super和直接调用非静态方法(图9)


java中静态方法中为什么不能使用this、super和直接调用非静态方法(图11)


java中静态方法中为什么不能使用this、super和直接调用非静态方法(图13)

这个要从java的内存机制去分析,首先当你New 一个对象的时候,并不是先在堆中为对象开辟内存空间,而是先将类中的静态方法(带有static修饰的静态函数)的代码加载到一个叫做方法区的地方,然后再在堆内存中创建对象。所以说静态方法会随着类的加载而被加载。当你new一个对象时,该对象存在于对内存中,this关键字一般指该对象,但是如果没有new对象,而是通过类名调用该类的静态方法也可以。

程序最终都是在内存中执行,变量只有在内存中占有一席之地时才会被访问,类的静态成员(静态变量和静态方法)属于类本身,在类加载的时候就会分配内存,可以通过类名直接去访问,非静态成员(非静态变量和非静态方法)属于类的对象,所以只有在类的对象创建(实例化)的时候才会分配内存,然后通过类的对象去访问。

在一个类的静态成员中去访问非静态成员之所以会出错是因为在类的非静态成员不存在的时候静态成员就已经存在了,访问一个内存中不存在的东西当然会出错。


在《Java编程思想》P86页有这样一段话:

  “static方法就是没有this的方法。在static方法内部不能调用非静态方法,反过来是可以的。而且可以在没有创建任何对象的前提下,仅仅通过类本身来调用static方法。这实际上正是static方法的主要用途。”

  这段话虽然只是说明了static方法的特殊之处,但是可以看出static关键字的基本作用,简而言之,一句话来描述就是:

  方便在没有创建对象的情况下来进行调用(方法/变量)。

  很显然,被static关键字修饰的方法或者变量不需要依赖于对象来进行访问,只要类被加载了,就可以通过类名去进行访问。

  static可以用来修饰类的成员方法、类的成员变量,另外可以编写static代码块来优化程序性能。

1)static方法

  static方法一般称作静态方法,由于静态方法不依赖于任何对象就可以进行访问,因此对于静态方法来说,是没有this的,因为它不依附于任何对象,既然都没有对象,就谈不上this了。并且由于这个特性,在静态方法中不能访问类的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都是必须依赖具体的对象才能够被调用。

  但是要注意的是,虽然在静态方法中不能访问非静态成员方法和非静态成员变量,但是在非静态成员方法中是可以访问静态成员方法/变量的。举个简单的例子:

  在上面的代码中,由于print2方法是独立于对象存在的,可以直接用过类名调用。假如说可以在静态方法中访问非静态方法/变量的话,那么如果在main方法中有下面一条语句:

  MyObject.print2();

  此时对象都没有,str2根本就不存在,所以就会产生矛盾了。同样对于方法也是一样,由于你无法预知在print1方法中是否访问了非静态成员变量,所以也禁止在静态成员方法中访问非静态成员方法。

  而对于非静态成员方法,它访问静态成员方法/变量显然是毫无限制的。

  因此,如果说想在不创建对象的情况下调用某个方法,就可以将这个方法设置为static。我们最常见的static方法就是main方法,至于为什么main方法必须是static的,现在就很清楚了。因为程序在执行main方法的时候没有创建任何对象,因此只有通过类名来访问。

  另外记住,即使没有显示地声明为static,类的构造器实际上也是静态方法

2)static变量

  static变量也称作静态变量,静态变量和非静态变量的区别是:静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。

  static成员变量的初始化顺序按照定义的顺序进行初始化。

3)static代码块

  static关键字还有一个比较关键的作用就是 用来形成静态代码块以优化程序性能。static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。

  为什么说static块可以用来优化程序性能,是因为它的特性:只会在类加载的时候执行一次。下面看个例子:

12345678910111213class Person{    private Date birthDate;         public Person(Date birthDate) {        this.birthDate = birthDate;    }         boolean isBornBoomer() {        Date startDate = Date.valueOf('1946');        Date endDate = Date.valueOf('1964');        return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate) <>0;    }}

  isBornBoomer是用来这个人是否是1946-1964年出生的,而每次isBornBoomer被调用的时候,都会生成startDate和birthDate两个对象,造成了空间浪费,如果改成这样效率会更好:

12345678910111213141516class Person{    private Date birthDate;    private static Date startDate,endDate;    static{        startDate = Date.valueOf('1946');        endDate = Date.valueOf('1964');    }         public Person(Date birthDate) {        this.birthDate = birthDate;    }         boolean isBornBoomer() {        return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate) <>0;    }}

  因此,很多时候会将一些只需要进行一次的初始化操作都放在static代码块中进行。

二.static关键字的误区

1.static关键字会改变类中成员的访问权限吗?

  有些初学的朋友会将java中的static与C/C++中的static关键字的功能混淆了。在这里只需要记住一点:与C/C++中的static不同,Java中的static关键字不会影响到变量或者方法的作用域。在Java中能够影响到访问权限的只有private、public、protected(包括包访问权限)这几个关键字。看下面的例子就明白了:

  提示错误'Person.age 不可视',这说明static关键字并不会改变变量和方法的访问权限。

2.能通过this访问静态成员变量吗?

  虽然对于静态方法来说没有this,那么在非静态方法中能够通过this访问静态成员变量吗?先看下面的一个例子,这段代码输出的结果是什么?

123456789101112public class Main {      static int value = 33;    public static void main(String[] args) throws Exception{        new Main().printValue();    }    private void printValue(){        int value = 3;        System.out.println(this.value);    }}


33

  这里面主要考察队this和static的理解。this代表什么?this代表当前对象,那么通过new Main()来调用printValue的话,当前对象就是通过new Main()生成的对象。而static变量是被对象所享有的,因此在printValue中的this.value的值毫无疑问是33。在printValue方法内部的value是局部变量,根本不可能与this关联,所以输出结果是33。在这里永远要记住一点:静态成员变量虽然独立于对象,但是不代表不可以通过对象去访问,所有的静态方法和静态变量都可以通过对象访问(只要访问权限足够)。

3.static能作用于局部变量么?

  在C/C++中static是可以作用域局部变量的,但是在Java中切记:static是不允许用来修饰局部变量。不要问为什么,这是Java语法的规定。



java中静态方法中为什么不能使用this,super和直接...

答:this和super本身就是表示一个对象。而静态方法是属于类的,不属于任何一个对象,在调用静态方法时,this和super以及其他非静态方法无法知道你指的是哪一个对象。虽然你用的是对象名.静态方法名,但是实际上还是在调用一个类的静态方法。A.static...

java中静态方法中为什么不能使用this,super和直接...

答:静态方法是在类里面的,是由类直接调用的. this指的是调用该方法的对象. 熟读上面两点,然后看;例子 calss A{ static void add(){ this.go(); } void go(){} } 如果用A.add(); 我们说add里面的this指的是调用当前add方法的对象, 可是add是由类A直...

为什么java中的this和super只能用在非静态方法中

答:静态的方法可以在没有创建实例时使用,而申明为非静态的成员变量是一个对象属性,它只有在对象存在时引用,因此如果在对象未创建实例时我们在静态方法中调用了非静态成员方法自然是非法的,所以编译器会在这种时候给各错误.

请问为什么静态方法中不能调用非静态方法

答:静态方法的内存分配时间与实例方法不同 当程序开始运行时,静态方法已经在内存中被分配了空间,有了入口地址,所以可以通过"类名.方法名"直接调用 而实例方法只有在创建了该类的对象以后才分配内存 也就是说程序开始运行后静态方法已经有了入口地址...

java中静态方法中不能调用非静态方法

答:静态static方法中不能调用非静态non-static方法是值得是不能直接调用non-static方法 public class Test01 { public static void main(String[] args) { hello(); } public void hello() { } } 是指的这种 在静态的main方法中,直接调用了本类的非...

JAVA 里既然静态方法无法调用非静态方法,那主方法...

答:静态方法不可以调非静态全局变量,从内存的角度看,就是当类被加载的时候静态方法和静态属性(全局静态变量)被加载到内存中,就是在内存中开辟一段内存地址用来保存静态方法和静态属性,这时候没有被实例化的类在内存中是不存在的,所以静态方...

java非静态方法中能直接调用静态方法么

答:可以,静态方法里面掉不了非静态的。因为静态方法在类初始化的时候就有了,非静态方法还不存在。。。

JAVA中 在static方法内部能否调用非静态方法

答:static方法内部不能直接调用非静态方法, 可以在调用之前实例化非静态方法所在的类,再用类点方法来调用。 例:非静态方法是className类里面的method(); className cn=new className(); cn.method(); 这样就可以了。

Java静态方法为什么不能访问非静态方法

答:静态方法被调用时是不new的。如果方法中有非静态方法的方法,你让我调用时怎么办

java主方法如何调用非静态方法

答:java主方法调用非静态方法的步骤: 1、新建一个类,本例类名“NoStaticMethod”,声明一些成员变量,创建一个主方法main(),一个非静态方法Method_1()。 2、类的全部代码。 ** * Created by Administrator on 2016/7/25. */ public class NOstaticM...

为您准备的相关内容:

  • Java中的static关键字解析
  • android开发中使用static的方法好,还是...
  • 静态方法与实例方法的区别
  • C++ 类的静态成员(static) - 开发者在线...
  • c++学习笔记(五):c++中的static关键字...
  • C#中静态与非静态方法比较
  • java中2个不同类的变量调用
  • Java中static变量有什么作用?一般用在什...
  • >>> 温馨提示:您还可以点击下面分页查看更多相关内容 <<<

    头条

    热门

    24小时热评

    热点排行榜

    Copyright ? 2012-2016 tuxi.com.cn 版权所有 京ICP备10044368号 京公网安备11010802011102号 关于我们 | 广告服务 | 诚聘英才 | 联系我们 | 友情链接 | 免责申明