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

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


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

[这个贴子最后由 sunweiqin 在 2017-07-04 09:57:45 重新编辑]
  Java面向对象编程-->图形用户界面(下)
  JavaWeb开发-->在Web应用中访问Web服务
  JSP与Hibernate开发-->JPA API的高级用法
  Java网络编程-->基于UDP的数据报和套接字
  精通Spring-->Vue指令
  Vue3开发-->Vue组件开发高级技术
  BIO、NIO和AIO的区别、三种IO的原理与用法
  JDK14的新特性
  Java方法的嵌套与递归调用
  Eclipse的安装配置
  Java注解的定义和使用
  深入分析synchronized实现原理
  正则表达式范例
  正则表达式性能调优
  java 支持分词的高性能拼音转换工具,速度是 pinyin4j 的两倍
  Java入门实用代码:获取所有线程
  Java 入门实用代码:从 List列表中 截取子列表
  Java入门实用代码:将文件内容复制到另一个文件
  Java 入门实用代码:数组扩容
  Java入门实用代码:字符串小写转大写
  Java入门实用代码:字符串替换
  更多...
 IPIP: 已设置保密
楼主      
该用户目前不在线 sunweiqin 
  

威望: 0
级别: 高级天王 [荣誉]
魅力: 680
经验: 680
现金: 1528
发文章数: 191
注册时间: 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前沿技术。  联系我们
如有技术文章涉及侵权,请与本站管理员联系。