黑马程序员技术交流社区
标题: 一个关于静态使用的疑问 [打印本页]
作者: 韩伟 时间: 2012-7-17 08:39
标题: 一个关于静态使用的疑问
本帖最后由 韩伟 于 2012-7-17 11:34 编辑
刚才敲代码的时候突然想到这样一个问题:
毕老师曾经这样总结静态
1、静态方法只能访问静态成员(方法、变量)。
非静态方法可以访问静态成员吗?可以!!!即可以访问静态,也可以访问非静态。
2、静态方法中不可以定义this,super关键字。
因为静态优先于对象存在,所以静态方法中不可以出现this。
3、主函数是静态的。
那我我想问的就是:
静态方法不允许调用非静态的属性和方法,只能调用静态的属性和方法。但是主函数也是静态啊,那么主函数(static方法)调用非静态方法的原理是什么呀?难道就是因为它是主函数所以有特权!另外在主函数(static方法)中我们经常创建某个类的实例,再利用其引用变量调用它的非静态方法?是不是说明在主函数中可以通过某种方法实现调用非静态方法?具体是什么原理?
作者: 樊佰轩 时间: 2012-7-17 08:44
从我们之前写的程序中,我们找不出一个是主函数调用非静态方法的例子,在主函数类中,往往定义和主函数并列的静态函数并在主函数中调用,而其他函数的使用都是通过创建其他类的对象,然后通过该对象调用该类的方法。(这里可能你是误解的调用了非静态函数)
作者: 夏儒日 时间: 2012-7-17 08:58
静态虽好但只能访问静态,主函数也没有例外。虽然在定义主函数的时候我们调用了非静态的成员,但是你忽略了一点:在你调用非静态的成员之前是不是要先创建一个对象呀?你如果不创建对象是不能访问静态的成员的! 既然你都创建了对象那么不论是静态还是非静态都能调用了!
主函数也是不能直接调用非静态方法的,可以分两种情况说明:
(1)当该非静态方法与主函数在一个类中,示例代码如下:
class StaticDemo
{
public void run()
{
System.out.println("run");
}
public static void main(String[] args)
{
//调用run方法的方式
}
}
对于这种情况,如果想调用非静态的run方法,只能是创建本类的对象,StaticDemo sd = new StaticDemo();然后对象调用sd.run();如果run方法是静态的,那直接调用run()。
(2)该静态方法与主函数不在同一类中,示例代码如下
class Static
{
public void run()
{
System.out.println("run");
}
}
class StaticDemo
{
public static void main(String[] args)
{
//调用run()方法的方式
}
}
如果在主函数中调用非静态run方法,也是只能创建所属类的对象,Static s = new Static();然后对象调用s.run();这都和上面是一样的。
如果如果run方法是静态的,那直接类名调用Static.run()(思想与上面是一样的)。所以可以看出主函数也是不能直接调用非静态的方法的。
作者: 刘真 时间: 2012-7-17 10:24
夏儒日 发表于 2012-7-17 08:58
静态虽好但只能访问静态,主函数也没有例外。虽然在定义主函数的时候我们调用了非静态的成员,但是你 ...
学习了,只知道要创建对象来调用属性或方法,还从来没思考过这个问题,恍然大悟!
作者: 陈冲 时间: 2012-7-17 10:36
主函数并不是直接调用静态方法,而是通过实例化对象之后,通过对象来调用方法;
这样就不存在静态函数调用非静态方法了
作者: 王宝康 时间: 2012-7-17 10:47
夏儒日 发表于 2012-7-17 08:58
静态虽好但只能访问静态,主函数也没有例外。虽然在定义主函数的时候我们调用了非静态的成员,但是你 ...
学习了,逛论坛的意义就在于此,能发现自己的好多疑问,以及比自己对某一问题更深入,更全面的认识。
作者: 王宝康 时间: 2012-7-17 11:18
咱也来一段,作为程序入口的main()方法,把main()方法定义为静态方法,这样java虚拟机只要加载来main()方法所属的类,就能执行main()方法,而无需先创建这个类的实例,在main()静态方法中不能访问实例变量和实例方法。- package demo;
- public class Sample {
-
- /**
- * @param args
- */
- int x ;
- void method(){};
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- x = 9;//实例变量x不是静态的,不能直接使用,这样会没有所属的,出现编译错误
- this.x = 9;//main方法为静态方法,不会不能出现this关键字,编译错误
- method();//实例方法method()非静态,不能直接调用,出现编译错误
- this.method();//编译错误
- }
- }
-
复制代码 正确的做法是:通过Sample实例的引用来访问实例方法和实例变量- public class Sample {
-
- /**
- * @param args
- */
- int x ;
- void method(){};
- public static void main(String[] args) {
- Sample s = new Sample();
- s.x = 9;//合法,因为不是静态的,所以就应该有个所属,即实例s的变量
- s.method();//合法,原因同上
- }
- }
复制代码
作者: 周坤 时间: 2012-7-17 11:19
static是一个修饰符,只用于修饰成员方法和成员变量。它的出现就是为了共享那需要共享的数据,那么当然,静态方法中的属性同样需要是静态的。
在加载类时,静态和非静态方法都会被加载,不执行。只要记住,静态方法存放在内存的方法区的静态区,它是属于类的,而非静态方法存放方法区的非静态区,它是属于对象的。没有对象,是无法调用非静态方法的。
作者: 党巾水 时间: 2012-7-17 11:53
主函数调用静态方法时直接调用,调用非静态方法时先创建对象,这也是面向对象思想的体现。对象一般是通过一个类去创建,类的加载有类加载器解决。类加载的终极母亲不是java写的,而是用系统环境语言写的。所以主函数中可以创建对象,然后再用对象去调用其拥有的非静态方法。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |