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

在编程的时候,常常遇到这样的编译错误,提示说,不允许在静态方法中直接访问this关键字、实例变量和实例方法。我现在知其然不知所以然,为什么不允许这样呢?


程序猿的技术大观园:www.javathinker.net

[这个贴子最后由 sunweiqin 在 2017-07-04 09:57:45 重新编辑]
  Java面向对象编程-->Java语言的基本语法和规范
  JavaWeb开发-->JavaWeb应用入门(Ⅰ)
  JSP与Hibernate开发-->数据库事务的并发问题的解决方案
  Java网络编程-->通过JDBC API访问数据库
  精通Spring-->通过Vuex进行状态管理
  Vue3开发-->Vue Router路由管理器
  解决javac编译错误: 编码UTF8/GBK的不可映射字符
  面试官:NIO的优化实现原理了解吗?图文结合教你如何正确避坑
  从实战角度解读JVM:类加载机制+JVM调优实战+代码优化!
  超详细的Java运算符修炼手册(优秀程序员不得不知道的运算技...
  使用javaNIO实现C/S模式的通信
  Eclipse使用指南:常用视图(View) 的用法
  Java设计模式:迭代器模式
  Java入门实用代码:获取远程文件大小
  Java入门实用代码: List 列表中元素的替换
  Java入门实用代码:集合转数组
  Java入门实用代码:遍历目录
  Java入门实用代码:将文件内容复制到另一个文件
  通过java.net.URL类连接HTTP服务器时获取响应结果的头部信息
  native2ascii.exe 的Java实现类
  Java Pattern和Matcher字符匹配详解
  更多...
 IPIP: 已设置保密
楼主      
该用户目前不在线 sunweiqin 
  

威望: 0
级别: 高级天王 [荣誉]
魅力: 480
经验: 480
现金: 1128
发文章数: 171
注册时间: 2016-09-12
 消息  查看  搜索  好友  邮件  复制  引用


成员方法分为静态方法和实例方法。用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属性。
发文章时间 2017-07-04 10:01:32
 IPIP: 已设置保密 1 楼     
1页 2条记录 当前第1
发表一个新主题 开启一个新投票 回复文章


中文版权所有: JavaThinker技术网站 Copyright 2016-2026 沪ICP备16029593号-2
荟萃Java程序员智慧的结晶,分享交流Java前沿技术。  联系我们
如有技术文章涉及侵权,请与本站管理员联系。