黑马程序员技术交流社区

标题: 方法参数可以是static吗? [打印本页]

作者: 瞿乐    时间: 2012-8-5 01:53
标题: 方法参数可以是static吗?
如题。刚看到 内部类要使用的变量,传参时候要使用final修饰,延长生命周期,满足字节码文件的使用。
忽然想到的这个问题, 如果可以用static修饰的话,会是在什么情况下使用,如果不可以,说说为什么会不可以,举个例。
作者: 杨文宇    时间: 2012-8-5 03:19
static不能修饰方法参数和局部变量:

JVM对每种类型的变量有自己的存储区,static有专门的存储区,局部也是

所以局部和静态的概念其实是相冲的,不可能同时作为标识符去指定一个变量

你只要做个简单的例子就知道了,方法中声明的都是局部变量,如果你强行加上静态呢?
public static void f(){
static init j=0;
}

根本就无法通过编译,因为JVM不知道把变量往那个存储区域放

所以方法里面不能有静态变量。局部内部类能调用外部的静态变量。
作者: 徐小骥    时间: 2012-8-5 18:19
首先我们给出一段没有使用sataic修饰成员的代码:
Class Mytest{
    String name;
    String country;
    private void show(){
        System.out.println( country+"****"+name);
         }
    }
Class staticDome{
    private static void main(String[] args){
    Mytest mt=new Mytest();
    mt.country="China";
    mt.name="黑马";
    mt.show();
    }
}
代码(1)

static是一个修饰符,用于修饰成员变量和成员函数。首先,我们可以粗略了解static的特点:
1、可以直接用类名调用;
2、被所有对象共享;
3、优先于对象存在;
4、随着类的加载而加载,随着类的消失而消失。

1、可以直接用类名调用 :
当成员变量和成员函数被static修饰之后,除了可以被对象调用外还多了一种调用方法!它可以直接用类名调用(格式为:类名.静态成员),如代码(2),代码(3)
Class Mytest{
    String name;
    static String country="China";
    }
Class staticDome{
    private static void main(String[] args){
    Mytest mt=new Mytest();
    System.out.println(mt.country);
    }
}
代码(2)

Class Mytest{
    String name;
    static String country="China";
    }
Class staticDome{
    private static void main(String[] args){
    System.out.println( Mytest.country);
    }
}
代码(3)
在代码(2)中,我们发现在main函数中先创建了一个Mytest对象,通过这个对象来调用country变量,而在代码(3)中,则是在main函数中直接调用Mytest类的类名调用country变量。

2、被所有对象共享:
Class Mytest{
    String name;
    String country;
    private void show(){
        System.out.println( country);
         }
    }
Class staticDome{
    private static void main(String[] args){
    Mytest mt1=new Mytest();
    mt1.country=“China”;
   Mytest mt2=new Mytest();
    mt2.country=“China”;
    mt1.show();
    mt2.show();
    }
}
代码(4)

Class Mytest{
    String name;
    static String country="China";
    }
Class staticDome{
    private static void main(String[] args){
    Mytest mt1=new Mytest();
   Mytest mt2=new Mytest();
    System.out.println(mt1.country);
    System.out.println(mt2.country);
    }
}
代码(5)
对比代码(4)和代码(5),在代码(5)中,mt1和mt2共享了静态变量country;而代码(4)mt1和mt2中各自开辟了一个country空间,且这个空间的值是完全一样的!这就照成了内存空间的浪费!所以当多个对象拥有共同变量时,我们可以将这个变量定义成静态变量!

3、优先于对象存在:
在代码(2)中,我们在使用Mytest这个类时,Mytest这个类要进内存,当Mytest进内存时,country已经在内存中开辟好了空间,这个空间的值是Chain,这时候,你能够找到country,但是找不到name,只有创建对象的时候,才能找到name,我们称name为成员变量或实例变量,而country为静态的成员变量或类变量。

4、随着类的加载而加载,随着类的消失而消失(说明生命周期长):
在代码(2)中,我们创建对象mt的时候,country就已经存在了,当mt消失后,country依然存在,当Mytest这个类消失的时候,country才消失!所以类中的静态变量的生命周期长于对象!当类中的静态变量过多时,就照成了内存空间的长时间被占用,也会照成空间的浪费。所以并不是静态变量越多越好!所以开发的时候要从实际出发,应该用静态的时候,我们才采用static!

实例变量和类变量的区别:
1、存放位置:类变量随着类的加载而存放于方法区中,而实例变量随着对象的建立存放于堆内存中。
2、生命周期:类变量的生命周期最长,随着类的消失而消失,而实例变量随着对象的消失而消失。

那么什么时候使用static?
      在我们创建一个实例(对象)时,通常使用new方法,这个类的数据空间才会被创建,其方法才能被调用。在创建多个对象具相同的数据,我们可以采用静态变量的情形,如代码(5);另一种情形就是希望某个方法不与包含它的类的任何对象关联在一起,直接通过类名调用,如代码(3);还有一个特殊的用法就是出现在内部类中,通常一个普通类不允许声明为静态的,只有一个内部类才可以,这时候这个声明的内部类可以直接作为一个普通的类来使用,而不需要实例一个外部类,如代码(6)。
Class Mytest{
  public static class test{
    test(){
        System.out.println("*******");
             }
          }
      }
Class staticDome{
    private static void main(String[] args){
    Mytest.test mt=new Mytest.test();//这之前不需要new一个Mytest
    }
}
代码(6)
作者: 瞿乐    时间: 2012-8-5 22:40
嗯嗯,我明白了
作者: 王龙彪    时间: 2012-8-5 22:46
static 是随着类一起加载的
方法是在创建对象后, 调用方法后才加载的, 要比被static 修饰的变量晚.
作者: 瞿乐    时间: 2012-8-5 22:54
嗯,明白了, 形参是 局部变量,局部变量不可以用static修饰,因为,static是类加载就会开辟内存,是这样的吧




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