>>分享Java编程技术,对《Java面向对象编程》等书籍提供技术支持 书籍支持  卫琴直播  品书摘要  在线测试  资源下载  联系我们
发表一个新主题 开启一个新投票 回复文章 您是本文章第 25857 个阅读者 刷新本主题
 * 贴子主题:  请教:为什么在静态方法中不能直接访问this关键字、实例变量和实例方法 回复文章 点赞(0)  收藏  
作者:sunweiqin    发表时间:2017-07-04 10:01:32     消息  查看  搜索  好友  邮件  复制  引用

成员方法分为静态方法和实例方法。用static修饰的方法叫静态方法,或类方法。静态方法也和静态变量一样,不需创建类的实例,可以直接通过类名来访问,例如:

public class Sample1 {
  public static int add(int x, int y) {  //静态方法
    return x + y;
  }
}
public class Sample2 {
  public void method() {
    int result =Sample1.add(1,2);  //调用Sample1类的add()静态方法
    System.out.println("result= " + result);
  }
}

因为静态方法不需通过它所属的类的任何实例就会被调用,因此在静态方法中不能使用this关键字,也不能直接访问所属类的实例变量和实例方法,但是可以直接访问所属类的静态变量和静态方法。例如在Voter类中,count变量是静态变量,表示所有选民的共同投票数,name变量是实例变量,表示每个具体选民对象的名字。以下程序在Voter类的静态方法printVoteResult()中直接访问count和name变量:

public class Voter{
  private static final int MAX_COUNT=100; //静态变量,最大投票数,到达此数就停止投票
  private static int count; //静态变量,投票数
  private static Set<Voter> voters=new HashSet<Voter>(); //静态变量,存放所有已经投票的选名
  private String name; //实例变量,投票人姓名

  /** 打印投票结果  */
  public static void printVoteResult(){
    System.out.println("当前投票数为:"+count);  //合法
    System.out.println("选民的姓名:"+name);  //编译错误
    System.out.println("选民的姓名:"+this.name);  //编译错误
    ……
  }
}

不妨用反证法来证明在printVoteResult()方法中不能直接访问name变量或者this.name变量。假定以上程序编译成功,那么当Java虚拟机在执行以下代码时会遇到问题:

Voter.printVoteResult();  //调用Voter类的静态方法printVoteResult()

Java虚拟机在执行静态方法printVoteResult()时,它能顺利地从Voter类的方法区内找到count静态变量,而对于name变量或this.name变量,Java虚拟机无从判断到底属于哪个Voter对象,Java虚拟机只会在包含Voter类信息的方法区内寻找该量,而不会到存放所有Voter对象的堆区去寻找它,所以Java虚拟机无法找到name变量或this.name变量。
由此可见,在静态方法中不能直接访问所属类的实例变量或实例方法,因为Java虚拟机无法定位它们。如果程序中出现这样的操作,Java编译器会生成以下编译错误:
在静态方法内不允许访问非静态变量。

那么假如printVoteResult()方法需要访问某个特定Voter对象的name属性,该怎么办呢?必须通过Voter对象的引用来访问name属性。例如:

public static void printVoteResult(){
  System.out.println("当前投票数为:"+count);
  System.out.println("参与投票的选民名单如下");

  for(Voter voter : voters){  //遍历voters集合,从voters集合中依次取出每个Voter对象
    System.out.println(voter.name);  //打印这个Voter对象的name属性
  }
}

以上程序从voters集合中依次取出每个Voter对象,然后打印它的name属性。程序以voter.name的形式来访问name变量,使Java虚拟机能明确地知道到底访问哪个Voter对象的name属性。
网站系统异常


系统异常信息
Request URL: http://www.javathinker.net/WEB-INF/lybbs/jsp/topic.jsp?postID=248&replyID=249&skin=1&pages=1

java.lang.NullPointerException

如果你不知道错误发生的原因,请把上面完整的信息提交给本站管理人员