黑马程序员技术交流社区

标题: 静态问题 [打印本页]

作者: 莫运飞    时间: 2012-4-3 21:14
标题: 静态问题
静态是什么时候使用的?什么时候定义静态函数? 希望在在这里可以得到简单又通俗易懂的看法,能举例说明就更好了。看视频实在糊涂,就是搞不懂。
作者: niceBoy    时间: 2012-4-3 21:48
用于修饰成员(成员变量和成员函数)
被修饰后的成员具备以下特点:
1、随着类的加载而加载
2、优先于对象存在
3、被所有对象所共享
4、可以直接被类名调用
使用注意:
1、静态方法只能访问静态成员
2、静态方法中不可以写this,super关键字,因为静态优先于对象存在,this代表的是对象

静态是什么时候使用的?
根据特点3:用于共享数据;(定义静态变量)
根据特点4,注意1:当功能内部没有访问到非静态数据,该功能可以定义成静态,因为方便使用。(定义静态函数)
作者: 刘晓康    时间: 2012-4-3 22:05
(1)可以实现某些特殊的设计模式:如Singleton;

(2)由于没有this指针,可以把某些系统API的回调函数以静态函数的形式封装到类的内部。因为系统API的回调函数通常都是那种非成员函数(孤立函数),没有this指针的。比如你可以在类的内部写一个线程函数供CreateThread创建线程用,如果没有静态函数,那么这种回调函数就必须定义成全局函数(非静态成员函数指针无法转换成全局函数指针),从而影响了OO的“封装性”。

(3)可以封装某些算法,比如数学函数,如ln,sin,tan等等,这些函数本就没必要属于任何一个对象,所以从类上调用感觉更好,比如定义一个数学函数类Math,调用Math::sin(3.14);如果非要用非静态函数,那就必须:
Math   math;
math.sin(3.14);
行是行,只是不爽:就为了一个根本无状态存储可言的数学函数还要引入一次对象的构造和一次对象的析构,当然不爽。而且既然有了对象,说不得你还得小心翼翼的定义拷贝构造函数、拷贝赋值运算符等等,对于一些纯算法的东西显然是不合适的。

(4)总之,从OOA/OOD的角度考虑,一切不需要实例化就可以有确定行为方式的函数都应该设计成静态的。
以上只是一些基本的考虑,并不是绝对的。绝对东西的只有一点:“静态函数不需要实例化就可以被调用,不会也不可以调用或操纵非静态成员”
作者: 张志阳    时间: 2012-4-3 22:38
static可以修饰成员变量和成员函数,被static定义的成员变量和函数随着类的加载而加载。
静态成员变量能够被类直接调用,它能在该类对象创建前被访问,而不用引用任何对象,声明为static的变量实质上就是全局变量。当声明一个对象时,并不产生static变量的拷贝,而是该类所有的实例变量共同拥有一个static变量。
静态函数有以下限制: 它们仅能调用其他的static 方法。它们只能访问static数据。它们不能以任何方式引用this 或super。

另外,关于加载顺序:类,类中静态变量,静态代码块,构造函数

下面例子验证了静态成员变量和函数的用法,注释的都是编译报错的部分。
class staticDemo
{
        static int a=3;        
        static int b=2+a;
        staticDemo(String msg)
        {
                System.out.println(msg);
        }
         void math(int x)
        {
                System.out.println("a "+a);
                System.out.println("b "+b);
                System.out.println("x "+x);
        }
        static
        {               
                System.out.println("b "+b);

                System.out.println("static bloc initialized");

                b=4*a;
        }
}
class staticDemo1
{
        int q=4;
        public void show()
        {
                System.out.println("show run");
        }
        
        public static void main(String [] a)
        {
               
                new staticDemo("constructor initialized").math(20);/*如果math方法是静态的,
                那么可以staticDemo.math(20);*/

                //System.out.println("a "+a);
                System.out.println("a "+staticDemo.a);

                //        System.out.println("q "+q);        
                System.out.println("q "+new staticDemo1().q);

                //show();
                new staticDemo1().show();

        }
        
        
}
作者: 郑苑东    时间: 2012-4-3 22:45
静态嘛。就是如果你想让你的成员变量编程唯一一个。就可以静态。让所有人共享这个东西。。。比如,有些东西我们只想它只有一个。。如电吧(一户家里一般只有一个电费,这是我们就像让电费是大家共享的,且唯一的)。。你家里不止你一个人,可是每个人都在用电。用的电的度数你们用的总和。而不是每个人个用个的。。一个人用了这个变量(电的度数)就会改变。同时其他人也一样。即使他们没用,这个变量时被共享的而且只有一个。相反亦然,他们的操作造成的改变也会回馈到你身上。。。。期望没把你弄晕了。。。
作者: 郑苑东    时间: 2012-4-3 22:47
当你这个方法没有用到非静态的一切吧。。那么你就可以定义成静态方法。。静态方法通过类名调用。不用通过生成对象实例来调用。。。。。
作者: 陈苓    时间: 2012-4-4 01:04
/*
什么时候用静态。

成员变量:如果该变量的数据值每个对象都一样,就将其静态修饰,否则,就是非静态。
成员函数:如果功能中没有访问到对象中的特有数据(非静态变量),那么就需要将该函数定义成静态,
                        因为创建对象调用除了浪费堆内存空间,没有意义。
*/

class Demo2
{
        static int num = 5;
        String name;
        static String country = "cn";

        void show()
        {
                System.out.println("show run:"+this.name);
        }

        static void show2()
        {
                System.out.println("show run");
        }
        static void show3()
        {
       
                System.out.println("num="+num);
        }
}

new Demo2().show();
new Demo2().show2();
Demo2.show2();
作者: 彭威    时间: 2012-4-4 11:20
我的关于静态的一些总结:
一 关键字:static:
1:修饰符,用于修饰成员(变量和函数),修饰的内容是被所有的对象所共享的;
2:可以直接被类名所调用的,格式是:类名.静态成员;
3:关于存储:修饰的内容存储在方法区里,随着类的加载而加载,随着类的消失而消失;
4:优先于对象存在的。
二 他修饰的变量称类变量,其余变量成为实例变量;区别:
1存储,前者存在方法区,而后者在堆内存
2生命周期:前者随着类的建立消失而建立消失,所以说其周期最长,而后者是随着对象相关的;
使用时注意:
1静态方法只能访问静态成员,而非静态方法二者皆可;
2静态方法中不可以定义this,super关键字,因为他是优先于对象先存在的;
三 利弊:
利:对对象共享的数据单独空间存储,节省空间;
弊:生命周期过长,
       访问有局限性,只能访问静态。
作者: 黄长利    时间: 2012-4-4 14:16
静态是随着类的加载而加载,优先于对象的存在而存在,在对象创建之前,已经随着类的加载存储在方法区中的静态方法区中,
静态主要用于定义共享数据,因为它不是随着对象的创建而放在堆内存中,
所以当创建多个对象都在使用这个静态的数据的时候,他们是共享这个数据,
对于此共享数据的影响也是直接体现在方法区,
也就是一个对象对这个数据的操作结果,其他对象也是会受到影响的,相当于数据已经在方法区中将其更新。
作者: 冯瀚冰    时间: 2012-4-4 14:33
额,我也正看这呢,感觉自己找不到正确、完整还比视频中更好的表达。。。。。建议放慢速度多看几遍
作者: 马超    时间: 2012-4-4 17:08
什么时候定义静态函数呢?

当功能内部没有访问到非静态数据(对象的特有数据,如:name,比方说:String
name属性、定义了一个show方法,show方法内部没有关系到name,那么就可以把函数
show定义成静态的

代码示例:
class Person
{
        String name;
        一、public static void show()
                {
                        System.out.println("haha");//show方法中没有访问到了非静态
                                                                                //的数据name,能够定义Static
                }
        二、public void show()
                {
                        System.out.println(name+"haha");//show方法中访问到了非静态
                                                                                //的数据name,不能定义Static
                }
}

class StaticDemo
{
        一、Person.show();
        二、Person p = new Person();
                p.show();
}
那么该功能可以定义成静态的。
*/




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2