A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 涂金哲 中级黑马   /  2012-6-20 10:24  /  4696 人查看  /  24 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 涂金哲 于 2012-7-4 09:33 编辑

当static关键字修饰方法,这个方法属于类,成为静态方法。静态方法可以使用对象来调用或者类调用。静态方法是随着类加载到内存中的,即静态方法可以独立到对象之外。在用对象调用静态方法时有个小问题不明白请大家帮帮忙哈,程序很简单,有个疑惑…
public class StaticTest {
  private static void method()  {
  System.out.println("静态方法");  
}
public void show()  {  
System.out.println("普通方法");
  }
public static void main(String[] args)  {  
StaticTest staticT=null;
  staticT.method();   
//staticT.show();//此处会发生空指针异常
}
} 运行结果看来,当我们用staticT=null,来调用普通方法时,会发生空指针异常,因为空表示引用变量指向的实例不存在,所以就谈不上调用实例的方法。但是,staticT=null却可以调用静态的方法,请问这个时候我们是说类在调用方法呢?还是staticT实例在调用呢???

评分

参与人数 1技术分 +1 收起 理由
职业规划-刘倩老师 + 1 赞一个!

查看全部评分

24 个回复

倒序浏览
StaticTest staticT=null;

staticT  是StaticTest的引用,引用就相当这个类。就像给一个人取一个绰号一样。 所以这里是相当于是类调用的。并不是实例,因为不存在实例。
回复 使用道具 举报
堆存储的是每个类非静态变量(类的实例成员属性)的值,和一个指向生成该对象的类的指针,所以staticT 应该是找他的类,然后类去调用静态方法吧。
回复 使用道具 举报
     这里你建了一个 空对象,只有引用,没有实例的class,声明后在栈里会有一个指针,但指向地址为空,没有分配堆内存。所以不能调用非静态方法,因为该非静态方法就没加载的内存中。  但是静态方法已经随着编译加载进去。 我认为这里应该还是 类 在调用静态方法。
回复 使用道具 举报
1,当成员被静态修饰后,就多了一个调用方式,除了可以被对象调用外,还可以直接被类名调用。格式:类名.静态成员,
2,修饰后占用方法区(数据区,共享区),不占栈堆内存。
你声明了一个指向空的对象,没有实例,所以不能调用非静态方法。
没有实例化不占内存,静态修饰后占用方法区(参见第二条),所以指向空的对象可以调用非静态方法。
回复 使用道具 举报
本帖最后由 胡大强 于 2012-6-20 12:48 编辑

static:是一个修饰符,用于修饰成员(成员变量、成员函数),当成员被静态修饰后,多了一种调用方式,除了被对象调用外,还可以直接被类名调用:类名.静态成员
静态实用注意事项:
       静态方法只能访问静态成员
       非静态方法可以访问静态也可以访问非静态
      静态方法中不可以定义this,super关键字,因为静态优先于对象存在,所以静态方法不可以出现this。
什么时候使用静态?
   当对象中出现共享数据时,该数据被静态所修饰。对象中特有数     据要定义成非静态存在于堆内存中。
什么时候定义静态函数?
  当功能内部没有访问到非静态数据(对象的特有数据)那么该功能可以定义成静态的;

所以应该是类在调用。。。
回复 使用道具 举报
李伟 中级黑马 2012-6-20 11:14:04
7#
StaticTest staticT=null//相当于给类取了个名字并没有创建出对象,所以应该是类在调用静态函数
回复 使用道具 举报
胡卿 中级黑马 2012-6-20 11:14:19
8#
主函数是静态的,只能调用静态方法,即使你不写StaticT=null,这样写
  1. class StaticTest {
  2. private static void method()  {
  3.   System.out.println("静态方法");  
  4. }
  5. public void show()  {  
  6. System.out.println("普通方法");
  7. }
  8. public static void main(String[] args)  {  
  9. //StaticTest staticT=null;
  10. // staticT.method();
  11.   method();
  12. // staticT.show();
  13. }}
复制代码
还是可以调用静态方法,所以调用静态方法可以在创立对象之前调用,不一定非要创建对象,它随着编译就已经加载

而主函数创立了空对象,引用函数时当然会引发空指针异常啦
回复 使用道具 举报
staticT 明明可以调用method 方法,您没理解我的问题……
回复 使用道具 举报
胡卿 发表于 2012-6-20 11:14
主函数是静态的,只能调用静态方法,即使你不写StaticT=null,这样写还是可以调用静态方法,所以调用静态方 ...

StaticT完全可以调用,您没有理解我的问题
回复 使用道具 举报
唐辉辉 发表于 2012-6-20 10:32
StaticTest staticT=null;

staticT  是StaticTest的引用,引用就相当这个类。就像给一个人取一个绰号一样 ...

那staticT.method ()可以打印结果,如何解释?
回复 使用道具 举报
我觉的这是一个对象调用,当你StaticTest staticT=null;
的时候,虽然建立了一类型为StaticTest 名为static的对象,指向为空,所以它的方法是不能被调用的,因为对象名有了,但是他没有被建立,普通方法也就没有被建立,当然不能被调用,但是静态方法却不同,静态方法是随着类的加载而加载,虽然对象名指向为空,但是静态方法已经有了,所以可以被调用,
不知道对不对  ,希望指教
回复 使用道具 举报
车风波 发表于 2012-6-20 10:36
堆存储的是每个类非静态变量(类的实例成员属性)的值,和一个指向生成该对象的类的指针,所以staticT 应该 ...

这种说法有点像……这种解释您是自己想的还是有资料可以证明?
回复 使用道具 举报
内存中静态方法都已经加载了,当然可以调用。。
我觉得楼上的回答都挺不错的,楼主不妨把自己的疑问说清楚,为什么别人没理解你的问题?
回复 使用道具 举报
涂金哲 发表于 2012-6-20 11:48
这种说法有点像……这种解释您是自己想的还是有资料可以证明?

以前在网上看到过,有一个指向生成该对象的类的指针
回复 使用道具 举报
yufeiant 发表于 2012-6-20 11:47
我觉的这是一个对象调用,当你StaticTest staticT=null;
的时候,虽然建立了一类型为StaticTest 名为stati ...

形式上看是对象调用……结果,不清楚,或许静态方法的类调用和对象调用之间有特殊的关系吧,期待有人指点
回复 使用道具 举报
闾丘日月 发表于 2012-6-20 11:50
内存中静态方法都已经加载了,当然可以调用。。
我觉得楼上的回答都挺不错的,楼主不妨把自己的疑问说清楚 ...

可能我的语言表达能力不好,我的问题是:null 对象访问普通方法会发生异常,而访问静态方法却没问题,。staticT .method 写成这种方式是类在调用方法?还是对象在调用方法?
回复 使用道具 举报
涂金哲 发表于 2012-6-20 13:27
可能我的语言表达能力不好,我的问题是:null 对象访问普通方法会发生异常,而访问静态方法却没问题,。stat ...

我的理解是,虚拟机或者说cpu能够正确找到那个方法,那么它就可以调用这个方法,静态方法随着类的加载而被加载,虚拟机只需要根据类名就知道静态方法在哪里从而可以正确调用,即使你用对象来调用静态方法,它还是会先找到对象属于哪个类,然后通过类来调用。
回复 使用道具 举报
StaticTest staticT=null;
只是创建了这个对象,但是你并没有实例化这个对象,那么这个对象的普通方法你是用不到的,这个可以理解吧,而static修饰的方法是可以用类名直接调用的。
虽然 staticT并没有被实例化,但是他却是 StaticTest类的引用,用 staticT调用static的方法就相当于 StaticTest 调用static方法 可以理解吧!
回复 使用道具 举报
StaticTest staticT=null;
只是创建了这个对象,但是你并没有实例化这个对象,那么这个对象的普通方法你是用不到的,这个可以理解吧,而static修饰的方法是可以用类名直接调用的。
虽然 staticT并没有被实例化,但是他却是 StaticTest类的引用,用 staticT调用static的方法就相当于 StaticTest 调用static方法 可以理解吧!
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 加入黑马