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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 高境 金牌黑马   /  2012-12-20 10:29  /  2030 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

什么时候使用静态,什么时候定义静态函数?静态代码块的好处?

评分

参与人数 2技术分 +1 黑马币 +20 收起 理由
Fateˉ似命守护 + 20
刘芮铭 + 1

查看全部评分

6 个回复

倒序浏览
静态的函数调用的时候不需要new,
static特点
1、随着类的加载而加载
也就是说:静态会随着类的消失而消失,说明他的生命周期最长
2、优先于对象存在
3、被所有对象所共享
4、可以直接被类名调用

什么时候使用静态呢?

要从两个方面入手
因为静态修饰的内容有成员变量和成员方法(函数)

评分

参与人数 1技术分 +1 收起 理由
刘芮铭 + 1

查看全部评分

回复 使用道具 举报
静态函数的使用:当函数中的内容与成员变量无关的时候,可以用static修饰函数。
好处:调用静态方法或静态变量的时候,可以用类名直接调用,而不需要new一个对象

评分

参与人数 1技术分 +1 收起 理由
刘芮铭 + 1

查看全部评分

回复 使用道具 举报
静态函数的使用:当功能内部没有访问到非静态数据(对象的特有数据),那么该功能可以定义为静态的
静态变量的使用:当对象中出现共享数据时,该数据被静态所修饰对象中的特有数据要定义成非静态存在于堆内存中
好处:对对象的数据进行单独空间的存储,节省空间,没有必要每个对象中的存储一份
          可以直接被类名调用。
坏处:生命周期过长。
          访问出现局限性。(只能访问静态)


回复 使用道具 举报
1.对象共享的数据,可以用静态。这样不用每个对象都开辟空间存放那个数据,可以节约内存。
2.如果方法没有用到对象的特有的东西,即没有使用到非静态变量还有非静态方法时,可以用静态方法。
3.静态代码块是类一加载就自动执行,相当于给类进行初始化。自己瞎想的,不知对不对,比如说一个程序,一打开就弹出个对话框,说欢迎你使用这个软件,像这东西,不是自己某些操作去调用它,你一运行程序他就自动执行了,所以这对话框代码就应该在静态代码块力。
回复 使用道具 举报
static的用法:

  static用于修饰:属性,方法,语句块,内部内

     语句块:在类内直接有大括号{},括号内有语句

     内部类:类内有另外的类

  作用:如果一个成员被声明为static,它就能够在它的类的任何对象创建之前被访问,而不必引用任何对象,声明为static的变量实质上就是全局变量,所以对象共享。(类相关:类属性,类方法)

  内存池:常驻内存,反复利用(数据库连接池常用)

  静态池:static属性

  class A{

      static int b = 0;

  }

  A a1 = new A();

  A a2 = new A();

  内存图:栈:a1,a2,分别指向堆内的两个对象

                堆:new A(),new A(),分别指向静态池中的静态值0

                静态池:0

  静态的属性/方法可以按照以下两种方式调用:

     a.new 对象(), 对象. 调用

     b.不创建对象,直接用类名.调用

  静态的属性/方法是在类加载时完成处理的,静态语句块仅在类加载时调用一次,非静态语句块在对象创建时调用。加载发生的条件:new 对象(声明不加载类,也不创建对象)

                                    类名.调用属性/方法

  静态方法的特征:

         类名.调用

         静态方法不能使用非静态变量,也不能调用非静态方法,反之可以

         父类静态方法只能被子类静态方法重写,发生多态时,静态方法调用父类重写前的

  例子1:父类静态方法只能被子类静态方法重写,发生多态时,静态方法调用父类重写前的

   public class Super {
     public static void test(){
         System.out.println("super");
     }
     public static void main(String[] args) {
        Super s = new Sub();
        s.test(); //发生多态是调用重写前的,得super,相当于Super.test();
     }
  }
  class Sub extends Super{
     public static void test(){ //只能被子类静态方法重写
        System.out.println("sub");
    }
}

  例子2:静态语句块仅在类加载时调用一次,非静态语句块在对象创建时调用,加载发生的条件:new 对象, 类名.调用属性/方法,声明不加载类,也不创建对象

public class TestBlock {
    static int i;
    static{  //静态语句块
         System.out.println("classLoading...");
    }
    {  //非静态语句块
         System.out.println("instance");
    }

}

public class Test {
     public static void main(String[] args) {
         System.out.println("begin");
         TestBlock tb; //声明既不加载类,也不创建对象
         System.out.println("declear");
         tb = new TestBlock();  //new对象,加载类,并创建对象
        System.out.println("over");
        TestBlock.i = 9;
        System.out.println(TestBlock.i);
     }
}

所以打印的结果:begin
                            declear
                            classLoading...
                            instance
                            over
                            9

但是以下将main方法和类写在一起,所得结果注意:

public class TestBlock {
    static int i;
    static{
        System.out.println("classLoading...");
    }
    {
        System.out.println("instance");
    }
    public static void main(String[] args) {
       System.out.println("begin");
       TestBlock tb;
       System.out.println("declear");
       tb = new TestBlock();
       System.out.println("over");
       TestBlock.i = 9;
       System.out.println(TestBlock.i);
    }
}                 

所以打印的结果:classLoading...
                             begin
                             declear
                             instance
                             over
                             9      

例子3: 静态方法不能使用非静态变量,也不能调用非静态方法,反之可以   

public class TestMethod {
    int i1 = 0;
    static int i2 = 0;
    public void test1(){
       i1 = 0; //非静态方法可以使用非静态变量
       i2 = 0; //非静态方法也可以使用静态变量
       System.out.println("no static");
    }
    public static void test2(){
       //i1 = 0; //静态方法不能使用非静态变量
       i2 = 0; //静态方法可以使用静态变量
       System.out.println("static");
    }
    public static void main(String[] args) {
       TestMethod.test2(); //静态方法可以直接用类名.调用
       //TestMethod.test1(); //非静态方法不能直接调用,需要new对象来调用
   }
}     

例子4:static变量是全局变量,每个对象共享        

public class TestField {
     static int i1 = 0; //类变量
     int i2 = 0; //实例变量
     public TestField(){
        i1++;
        i2++;
     }
     public static void main(String[] args){
        System.out.println(TestField.i1); //0
        TestField tf1 = new TestField();
        TestField tf2 = new TestField();
        System.out.println(tf1.i1); //2
        System.out.println(tf2.i1); //2
        System.out.println(tf1.i2); //1
        System.out.println(tf2.i2); //1
    }
}         

需要说明的是:类名.调用的时候,只类加载,不创建对象,所以不执行构造器中的代码,所以结果为0

                          i1为全局变量,每次创建对像的时候,执行构造器中的代码,数据更新一次,所以结果为2

                          i2为实例变量,每个用户访问数据都不变,只执行一次构造器中的代码,所以结果为1

例子5:Singleton 单例设计模式:类外只能有一个对象

             私有构造:private 构造

             提供一个static方法,返回本类对象

单例的目的:保证一个类只有单一的实例,也就是说你无法通过new来创建这个类的一个新实例。

单例的好处:当一个对象在程序内部只能有一个实例的时候,它可以保证我们不会重复创建,而是始终指向同一个对象

代码:

      第一种:在声明变量时实例化(也叫饿汉式单例模式),代码如下:

public class Singleton {

     private static Singleton instance = new Singleton();

     private Singleton(){}

  public static Singleton getInstance() {

       return instance;  

   }

}

第二种:把对象的创建放到方法里面去(也叫懒汉式单例模式),代码如下:

public class Singleton {

  private static Singleton instance = null;

       private Singleton(){}

  public static synchronized Singleton getInstance() {

       //也可以这样写:synchronized public static Singleton getInstance() {

      if (instance == null){

       instance = new Singleton();

           }

           return instance;

     }

}

各自的优缺点:

    第一种饿汉式:

    优点:在类加载初始化的时候就创建对象,调用getInstance的时候,没有同步方法,运行时性能较高。

    缺点:类加载速度慢,占用太多大的资源空间。

   第二种懒汉式:

    优点:避免了第一种方式的缺点, 同时,可以在多线程下运行安全。

    缺点:因为他使用了锁,在运行中效率慢。

测试:

public class Test {
   public static void main(String[] args) {
      Singleton s1 = Singleton.getInstance();
      Singleton s3 = Singleton.getInstance();
      System.out.println(s1==s3);  
   }
}

运行的结果:true

2.final的用法:

  final用于修饰:类,方法,变量(包括成员变量和局部变量)

       final的类无法继承,例:String/System类不可继承

       final的方法无法重写/覆盖,final类中所有方法都无法重写,因为final类无法继承

       final的变量必须显示赋值一次(only one)

       父类中非final的方法可以在子类中重写为final的方法

       final的属性没有set方法,可以有get方法,赋值可以直接赋,也可以在构造中赋

       只用final修饰的不是常量,因为final只管一层

       常量: 用static+final修饰的属性变量必须声明的同时赋初值,而且访问权限为public

           public static final int LIMIT = 9999; 常量名所有字母都大写,不同单词之间用下划线隔开

  例子1:

  public /*final*/ class Super {
    public /*final*/ void test(){}
}
class Sub extends Super{
public final void test(){}
}
回复 使用道具 举报
首先。 静态 就是说 谁都可以去用,包括(静态属性 静态方法)
举个例子吧:
比方说 以下代码
public class dept
{
    public static int sum(int a,int b)
    {
        int res=0;
        res=a+b;
        return res;
    }
public static void main(String[] args)
    {
        int a=1;
        int b=5;
        int res=sum(a, b);
        System.out.println(res);
    }
}

以上的代码 就是说有一个类dept  里面有一个静态的方法sum,在主方法main中 就可以直接用方法名称去调用。比较的方便。同样在主方法中    int res=sum(a, b);    也可以这样写  int res=dept.sum(a,b); 这样也是可以的。。
也就是说。
静态方法  ———————— 静态方法    (两者之间可以互相调用)
如果在一个类中,有静态方法,那么这个类中的主方法就可以直接用静态方法的名称就可以调用方法了。
如果不在一类中。那么就可以用静态方法所在的类名称去调用就可以了
很简单吧。。  
其实在方法的前面加了静态去修饰后,也就是简化了代码。 不用在类中去new一个对象,在用对象去点一个方法
明白了吗?
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马