精华内容
下载资源
问答
  • Java 中 static 关键字有4种使用场景,下面分别进行介绍:1.static 成员变量public class Student { // 静态成员变量 private static String SchoolName; private static int nums; // 非静态成员变量 private ...

    在 Java 中 static 关键字有4种使用场景,下面分别进行介绍:

    2e3549c89ebb47f785618090c7cf08cf.png

    1.static 成员变量

    public class Student {    // 静态成员变量    private static String SchoolName;    private static int nums;        // 非静态成员变量    private String name;    private int age;}

    在类中一个成员变量可用 static 关键字来修饰,这样的成员变量称为 static 成员变量,或静态成员变量。而没有用 static 关键字修饰的成员变量称为非静态成员变量。

    静态成员变量是属于类的,也就是说,该成员变量并不属于某个对象,即使有多个该类的对象实例,静态成员变量也只有一个。只要静态成员变量所在的类被加载,这个静态成员变量就会被分配内存空间。因此在引用该静态成员变量时,通常不需要生成该类的对象,而是通过类名直接引用。引用的方法是“类名 . 静态变量名”。当然仍然可以通过“对象名 . 静态变量名”的方式引用该静态成员变量。相对应的非静态成员变量则属于对象而非类,只有在内存中构建该类对象时,非静态成员变量才被分配内存空间。

    2.static 成员方法

    public class Student {    private static String SchoolName;    private static int nums;        // 静态成员方法    public static String getSchoolName() {        return Student.SchoolName;    }}

    Java 中也支持用 static 关键字修饰的成员方法,即静态成员方法。与此相对应的没有用 static 修饰的成员方法称为非静态成员方法。

    与静态成员变量类似,静态成员方法是类方法,它属于类本身而不属于某个对象。因此静态成员方法不需要创建对象就可以被调用,而非静态成员方法则需要通过对象来调用。

    特别需要注意的是,在静态成员方法中不能使用 this、super 关键字,也不能调用非静态成员方法,同时不能引用非静态成员变量。这个道理是显而易见的,因为静态成员方法属于类而不属于某个对象,而 this、super 都是对象的引用,非静态成员方法和成员变量也都属于对象。所以当某个静态成员方法被调用时,该类的对象可能还没有被创建,那么在静态成员方法中调用对象属性的方法或成员变量显然是不合适的。即使该类的对象已经被创建,也是无法确定它究竟是调用哪个对象的方法,或是哪个对象中的成员变量的。所以在这里特别强调这一点。

    3.static 代码块

    public class Student {    private static String SchoolName;    private static int nums;        // 静态代码块    static {        Student.SchoolName = "清风小学";        Student.nums = 0;    }}

    static 代码块又称为静态代码块,或静态初始化器。它是在类中独立于成员函数的代码块。static 代码块不需要程序主动调用,在JVM加载类时系统会执行 static 代码块,因此在static 代码块中可以做一些类成员变量的初始化工作。如果一个类中有多个 static 代码块,JVM将会按顺序依次执行。需要注意的是,所有的static 代码块只能在JVM加载类时被执行一次。

    4.static 内部类

    public class Student {    private static String SchoolName;    private static int nums;        // 静态内部类    static class test{        public test() {            System.out.println("Hello,student!" );        }    }}

    在 Java 中还支持用 static 修饰的内部类,称为静态内部类。静态成员内部类的特点主要是它本身是类相关的内部类,所以它可以不依赖于外部类实例而被实例化。静态内部类不能访问其外部类的实例成员(包括普通的成员变量和方法),只能访问外部类的类成员(包括静态成员变量和静态方法)。即使是静态内部类的实例方法(非静态成员方法)也不能访问其外部类的实例成员。

    展开全文
  • ERROR无法从静态上下文中引用非静态变量2012-06-16 20:58:52 分类:Java 什么是“static”? 学习过java、C++或C的人都应该认识这个关键字。用这个关键字修饰的变量叫做静态变量,有其特殊的作用...

    分类: Java

     

    什么是“static”?

    学习过java、C++或C的人都应该认识这个关键字。用这个关键字修饰的变量叫做静态变量,有其特殊的作用。在java中static也用来修饰静态方法和静态内部类。

     

    静态变量的特点:

    (1)生存周期:静态局部变量的生存周期也是整个源程序。当定义整个变量的函数结束时,整个变量并没有消失,他始终是存在的。

    (2)作用域:作用域与自动变量是一样的,只能在定义其的子函数中使用,当退出改函数时,整个变量虽然还是继续存在的,但是,已经不可以再使用它了。

    (3)整个静态变量如果没有赋初值,则默认为0.

    (4)在面向对象的编程语言JAVA中,对于静态变量,在没有实例化对象的情况下,也是可以直接使用的。(说明:这个特点特别适合用来定义一些常量,类似于C语言呢中的宏定义。例如:public static final double Pi=3.14;)

     

    静态方法特点:

    (说明:这边的静态方法也可以说成是静态函数)

    (1)不需要实例化对象,就可以直接使用的方法(函数)。

    (2)这个方法只可以访问这个类中的静态成员属性。

    (3)在java中,如果要在静态方法中,访问动态成员属性,那么首先要在这个方法中进行实例化,然后通过具体的对象来访问。

    小结:其实在静态方法中,都是要访问已经存在于内存空间的数据,比如静态数据,这个与对象无关,只要用到这个类,它就是存在的,无需初始化,是所有对象共同拥有的且只有一个副本。而动态的成员,必须要经过实例化,而且每个对象,都有一个副本,且所占内存地址不相同,所以在静态方法访问动态之前,要进行实例化。

     

    什么时候要用到静态域(静态属性)和静态方法?

    (1)如果一个方法要在项目启动的时候就运行,那么这个时候就一定要使用静态方法。最常见的例子就是main方法,这个方法要在实例化之前就开始运行了,所以必须要是静态方法。

    (2)对于要像C语言中那样,宏定义一个常量,就要用静态变量。

    (3)当一个变量要被多处共享的时候,这个时候最好用静态变量。

    (4)当一个方法要被反复的使用的时候,最好用静态方法。

     

    下面我就用具体的实例来说明:

     

    import java.util.*;

     

    public class A{

    final String name="First";

    public static final double Pi=3.14;

    public static void main(String[] args){

    // A a=new A();

    System.out.println("It is ok!");

    System.out.println(name);

    }

    void AA(){

    System.out.println("I am A.");

    System.out.println(name);

    }

    }

    这段程序是报错的,错误是“无法从静态上下文中引用非静态变量”,你一眼就可以看出来,是在static void main 中访问了动态的数据成员。我们知道,我们在定义类的时候必须要对类进行初始化,但是这个是为什么呢?因为在初始化的过程中,会对类中的动态属性成员进行初始化赋值。

    那么我们该如何修改上面的错误呢,我们借助上面的思想,可以想象一下如果我们对这个类进行实例化,是不是就可以通过对象来访问这个动态的属性。

     

     

    import java.util.*;

     

    public class A{

    final String name="First";

    public static final double Pi=3.14;

    public static void main(String[] args){

    A a=new A();

    System.out.println("It is ok!");

    System.out.println(a.name);

    a.AA();

    }

    public static void AA(){

    System.out.println("I am A.");

    System.out.println(Pi);//这个Pi是一个静态成员属性,可以直接访问

    }

    }

     

     

     

    我们可以发现,上面的问题被解决了。

    小结:在静态方法中可以直接访问静态属性,对于动态属性必须要进行实例化,然后通过具体的对象来访问相对应的属性

    转载于:https://www.cnblogs.com/lubocsu/p/5061280.html

    展开全文
  • 用这个关键字修饰的变量叫做静态变量,有其特殊的作用java中static也用来修饰静态方法和静态内部类。静态变量的特点:(1)生存周期:静态局部变量的生存周期也是整个源程序。当定义整个变量的函数结束时,整个...

    什么是“static”?

    学习过java、C++或C的人都应该认识这个关键字。用这个关键字修饰的变量叫做静态变量,有其特殊的作用。在java中static也用来修饰静态方法和静态内部类。

    静态变量的特点:

    (1)生存周期:静态局部变量的生存周期也是整个源程序。当定义整个变量的函数结束时,整个变量并没有消失,他始终是存在的。

    (2)作用域:作用域与自动变量是一样的,只能在定义其的子函数中使用,当退出改函数时,整个变量虽然还是继续存在的,但是,已经不可以再使用它了。

    (3)整个静态变量如果没有赋初值,则默认为0.

    (4)在面向对象的编程语言JAVA中,对于静态变量,在没有实例化对象的情况下,也是可以直接使用的。(说明:这个特点特别适合用来定义一些常量,类似于C语言呢中的宏定义。例如:public static final double Pi=3.14;)

    静态方法特点:

    (说明:这边的静态方法也可以说成是静态函数)

    (1)不需要实例化对象,就可以直接使用的方法(函数)。

    (2)这个方法只可以访问这个类中的静态成员属性。

    (3)在java中,如果要在静态方法中,访问动态成员属性,那么首先要在这个方法中进行实例化,然后通过具体的对象来访问。

    小结:其实在静态方法中,都是要访问已经存在于内存空间的数据,比如静态数据,这个与对象无关,只要用到这个类,它就是存在的,无需初始化,是所有对象共同拥有的且只有一个副本。而动态的成员,必须要经过实例化,而且每个对象,都有一个副本,且所占内存地址不相同,所以在静态方法访问动态之前,要进行实例化。

    什么时候要用到静态域(静态属性)和静态方法?

    (1)如果一个方法要在项目启动的时候就运行,那么这个时候就一定要使用静态方法。最常见的例子就是main方法,这个方法要在实例化之前就开始运行了,所以必须要是静态方法。

    (2)对于要像C语言中那样,宏定义一个常量,就要用静态变量。

    (3)当一个变量要被多处共享的时候,这个时候最好用静态变量。

    (4)当一个方法要被反复的使用的时候,最好用静态方法。

    下面我就用具体的实例来说明:

    import java.util.*;

    public class A{

    final String name="First";

    public static final double Pi=3.14;

    public static void main(String[] args){

    //A a=new A();

    System.out.println("It is ok!");

    System.out.println(name);

    }

    void AA(){

    System.out.println("I am A.");

    System.out.println(name);

    }

    }

    这段程序是报错的,错误是“无法从静态上下文中引用非静态变量”,你一眼就可以看出来,是在static void main 中访问了动态的数据成员。我们知道,我们在定义类的时候必须要对类进行初始化,但是这个是为什么呢?因为在初始化的过程中,会对类中的动态属性成员进行初始化赋值。

    那么我们该如何修改上面的错误呢,我们借助上面的思想,可以想象一下如果我们对这个类进行实例化,是不是就可以通过对象来访问这个动态的属性。

    import java.util.*;

    public class A{

    final String name="First";

    public static final double Pi=3.14;

    public static void main(String[] args){

    A a=new A();

    System.out.println("It is ok!");

    System.out.println(a.name);

    a.AA();

    }

    public static void AA(){

    System.out.println("I am A.");

    System.out.println(Pi);//这个Pi是一个静态成员属性,可以直接访问

    }

    }

    我们可以发现,上面的问题被解决了。

    小结:在静态方法中可以直接访问静态属性,对于动态属性必须要进行实例化,然后通过具体的对象来访问相对应的属性

    展开全文
  • 这个阶段中,执行上下文会分别创建变量对象,建立作用域,以及确定this指向。 代码执行阶段 创建完成后,就会开始执行代码,这个时候,会完成变量赋值,函数引用,以及执行其它代码。 变量对象...

    一个执行上下文的生命周期分为两个阶段

    • 创建阶段

       在这个阶段中,执行上下文会分别创建变量对象,建立作用域,以及确定this的指向。
      
    • 代码执行阶段

       创建完成后,就会开始执行代码,这个时候,会完成变量赋值,函数引用,以及执行其它代码。
      

    函数执行上下文的生命周期
    变量对象(Variable Object)
    变量对象的创建,依次经历了以下几个过程:

    1. 建立arguments对象。检查当前上下文中的参数,建立该对象下的属性与属性值。
    2. 检查当前上下文的函数声明,也就是使用function关键字声明的函数。在变量对象中以函数名建立一个属性,属性值为指向该函数所在内存地址的引用。如果函数名的属性已经存在,则会被新的引用所覆盖。
    3. 检查当前上下文中的变量声明,每找到一个变量声明,就在变量对象中以变量名建立一个属性,属性值为undefined。如果该变量名的属性已经存在(有个函数同名),为了防止同名的函数被修改undefined,则会直接跳过,原属性值不会被修改。
        function foo() {console.log('function foo')};
        var foo = 20; // 此为执行阶段 创建阶段跳过赋值
        console.log(foo); // 20
    

    foo的输出结果被覆盖是因为上面三条规则是适用于变量对象的创建过程中,也就是执行上下文的创建过程,而foo = 20 是在执行上下文的过程中运行的,输出结果就是20。对比下面的例子:

        console.log(fooAn); // function fooAn() {console.log('function fooAn')}
        function fooAn() {
          console.log('function fooAn')
        }
        var fooAn = 30;
    
        // 上面例子的执行顺序
    
        // 首先将所有函数声明放入变量对象中
        function fooAn() {
          console.log('function fooAn')
        }
    
        // 其次将所有的变量声明放入变量对象中,但是因为fooAn有同名函数,所以此时会跳过undefined的赋值
    
        // 继续执行代码
        console.log(fooAn); // function fooAn() {console.log('function fooAn')}
        fooAn = 30;
    

    所以用图表示:
    在这里插入图片描述

    在上面的例子中可以看到,function声明会比var声明优先级更高一点。

        // demo1
        function test1() {
          console.log(a); // undefined
          console.log(foo1()); // 2
          
          var a = 1;
          function foo1() {
            return 2;
          }
        }
        test1();
    

    在上例中,我们直接从test1()执行的上下文开始。全局作用域中运行test1()时,test1()的执行上下文开始创建:

    // 创建过程
    test1EC = {
    	// 变量对象
    	VO: {},
    	scopeChain: {}
    }
    
    //	VO 为Variable Object的缩写,即变量对象
    VO = {
    	arguments: {...},  //  在浏览器的展示中,函数的参数可能并不是放在arguments对象中,这里为了方便理解,我做了这样的处理
    	foo1: <foo1 reference>, //  表示foo1地址的引用
    	a: undefined
    }
    

    未进入执行阶段之前,变量对象中的属性都不能访问!但是在进入执行阶段后,变量对象转变为了活动对象,里面的属性都能被访问了,然后开始进行执行阶段的操作。

    • 变量对象和活动对象其实都是同一个对象,只是处于执行上下文的不同生命周期。不过只有处于函数调用栈栈顶的执行上下文中的变量对象,才会变成活动对象。
         // 执行阶段
         VO -> AO // Active Object
         AO = {
           arguments: {...},
           foo1: <foo1 reference>,
           a: 1,
           this: window
         }
    

    因此上面的例子执行顺序就变成了这样:

        function test1() {
          function foo1() {
            return 2;
          }
          var a;
          console.log(a);
          console.log(foo1());
          a = 1;
        }
    
        test1();
    

    全局上下文的变量对象
    以浏览器中为例,全局对象为window。
    全局上下文有一个特殊的地方,他的变量对象,就是window对象。而这个特殊,在this的指向上也同样适用,this的指向也是window。

    // 以浏览器中为例,全局对象为window
    // 全局上下文
    windowEC = {
      VO: Window,
      scopeChain: {},
      this: Window
    }
    

    除此之外,全局上下文的生命周期与程序的生命周期一致,只要程序运行不结束,比如关掉浏览器窗口,全局上下文就会一直存在。其它所有的上下文环境都能直接访问全局上下文的属性。

    展开全文
  • 有关方法调用问题,就是java中均为值传递,调用方法时,形参只方法内部起作用,那怎么修改能够修改对象属性呢?a.set(6);就可以修改某个属性值为6,这个是怎样实现呢?是set函数独有功能吗?(以后再回头...
  • “通过调用 Function 构造函数创建的函数对象,其内部的 [[scope]] 属性引用的作用域链中始终只包含全局对象。 通过函数声明或函数表达式创建的函数对象,其内部的 [[scope]] 属性引用的则是创建它们的执行环境...
  • var: 声明变量的作用域限制其声明位置的上下文中,而非声明变量总是全局的 由于变量声明(以及其他声明)总是任意代码执行之前处理的,所以代码中的任意位置声明 变量总是等效于代码开头声明 const: ...
  • 1,Spring对bean进行实例化, 2,Spring将值和bean的引用注入到bean对应的属性中, 3,··· 4··· 5``` ...bean的作用域 单列(Singleton 生go time):整个应用中,只创建一个bean的一...
  • 就是循环外面,接下来对e的引用仍然有效。这里有个问题容易被忽略,如果循环之前已经有一个同名对象存在,这个对象是被覆盖。如果有代码感知IDE中, IDE会提示变量是“被重新声明”, 但运行时却不会...
  • 闭包概念: 闭包是可以包含自由(未绑定到特定对象)变量代码块;这些变量不是这个代码...“闭包” 一词来源于以下两者结合:要执行代码块(由于自由变量被包含代码块中,这些自由变量以及它们引用的...
  • 注意for循环中变量的作用域 for e in collections: pass for 循环里, 最后一个对象e一直存在上下文中。就是循环外面,接下来对e的引用仍然有效。 这里有个问题容易被忽略,如果循环...
  • javascript里,我们可以用var 明确为函数变量声明作用域。 如果某个函数中使用了var ,那个变量就被视为一个局部变量,她只存在于这个函数上下文中;反正,如果没有使用var,那个变量将被
  • 关联文章地址这篇文章中绍介了“Python闭包与nonlocal”用法,因为nonlocal是Python3.0中新增关键字,python2.x不供提持支,文中提出Python2.x处理嵌套函数引用外部变量法方只有应用global 关键字...
  • 这听起来有些像局部变量,是,你可以将它理解为作用范围是全局局部变量.(听起来真绕口,但是我觉这样说你会懂) 它最经典应用场景就是数据库Connection,它可以保证同一个线程多个方法使用同一个...
  • 作用域链和闭包

    2020-11-28 16:57:46
        其实每个执行上下文变量环境中,都包含了一个外部引用,用来指向外部执行上下文,我们把这个外部引用称为 outer。当一段代码使用了一个变量时,JavaScript 引擎首先会“当前执行上下文”中查找该...
  • 作用域和执行上下文中先来讨论一下很多人函数传参是对象到底是按值传递还是按引用传递疑问? 函数传参 ECMAScript 中所有函数参数都是按值传递,变量有按值和按引用访问,而传参则只有按值传递。 看下列...
  • 活动对象就是作用域链上正在被执行和引用的变量对象。 执行上下文 当执行到一个函数时,就会进行一个准备工作,这里准备工作用专业名词将就是执行上下文, (准备工作包括执行栈中产生一个变量对象,这个执行...
  • 前言:最近细读Javascript高级程序设计,对于我而言,中文版,书中很多...文中绝大部分内容引用自《JavaScript高级程序设计第三版》。 执行环境(execution context) 执行环境(execution context,为了简单起...
  • 当一个函数调用时,引用了不是自己作用域内定义变量(通常称其为自由变量),则形成了闭包;闭包是代码块和创建该代码块上下文中数据结合。 例子: function mytest( ){ var test=10; return function...
  • 实际上,每个函数都是对象的属性——全局函数是 window 对象的属性——运行时函数的作用域即为函数被调用时函数所属的对象, 更严格的说法是保存了对函数的引用的对象: window.name = "the window object";...
  • 文中引用了经过个人加工其它作者内容,并非原创。学海无涯 什么是作用域?  作用域就是一套规则,用于确定何处以及如何查找变量(标识符)规则  伪代码帮助理解 function foo() { var a = 'ice'; ...
  •  这篇文章中绍介了“Python闭包与nonlocal”用法,因为nonlocal是Python3.0中新增关键字,python2.x不供提持支,文中提出Python2.x处理嵌套函数引用外部变量法方只有应用global 关键字定义全局变量,...
  • 1.前言前几天写了两篇关于c#位运算文章c#位运算基本概念与计算过程C#位运算实际运用在文中也提到了位运算实际作用之一就是合并整型,当时引用了一个问题:C# 用两个s...
  • 当一个函数调用时,引用了不是自己作用域内定义变量(通常称其为自由变量),则形成了闭包;闭包是代码块和创建该代码块上下文中数据结合。 例子: function mytest( ){ var test=10; return function...
  • 模仿块级作用域-立即执行函数 前言:最近细读Javascript高级程序设计,对于我而...文中绝大部分内容引用自《JavaScript高级程序设计第三版》。 JavaScript没有块级作用概念(ES5中没有)。这意味着块语句...

空空如也

空空如也

1 2 3 4 5 ... 9
收藏数 172
精华内容 68
关键字:

引用在文中的作用