88bifa必发唯一官网 4

Java中的static关键字深入分析

Java中的static关键字分析

一.static最首要字的用处

  在《Java编制程序观念》P8陆页有那样1段话:

  “static方法正是从未this的不2秘技。在static方法内部无法调用非静态方法,反过来是足以的。而且能够在未曾创设任何对象的前提下,仅仅通过类本人来调用static方法。那实在正是static方法的首要用途。”

  这段话固然只是表达了static方法的特殊之处,可是足以见到static关键字的为主职能,简单的讲,一句话来叙述正是:

  方便在并未有创造对象的处境下来实行调用(方法/变量)。

  很明显,被static关键字修饰的章程大概变量无需依据于对象来拓展走访,只要类被加载了,就能够通过类名去进行走访。

  static可以用来修饰类的积极分子方法、类的成员变量,别的能够编写制定static代码块来优化程序品质。

        static不能够修饰局地变量!!!

        static是验证那一个东西是属于全数类的

        而有的变量的功用域只好在他所属的{}之内。不容许是属于类或对象的。

        所以争执,故static不能够修饰局部变量

  static关键字是累累相恋的人在编写代码和读书代码时相遇的相比麻烦驾驭的三个注重字,也是各大商厦的面试官喜欢在面试时问到的知识点之一。下边就先讲述一下static关键字的用法和平平轻易误解的地点,最终列举了部分面试笔试中分布的关于static的试题。以下是本文的目录大纲:

1)static方法

  static方法一般称作静态方法,由于静态方法不借助于别的对象就足以拓展走访,由此对此静态方法来说,是从没有过this的,因为它不依据于任何对象,既然都未曾目的,就谈不上this了。并且由于这一个特点,在静态方法中无法访问类的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都以必须依据具体的对象工夫够被调用。

  可是要专注的是,即使在静态方法中无法访问非静态成员方法和非静态成员变量,不过在非静态成员方法中是可以访问静态成员方法/变量的。举个轻巧的例子:

88bifa必发唯一官网 1

  在上边的代码中,由于print二方法是单身于对象存在的,能够一直用过类名调用。假诺说能够在静态方法中做客非静态方法/变量的话,那么只要在main方法中有上面一条语句:

  MyObject.print2();

  此时目的都未曾,str二根本就不设有,所以就能够产生争辨了。一样对于措施也是壹律,由于您不能够预见在print1格局中是还是不是访问了非静态成员变量,所以也禁止在静态成员方法中走访非静态成员方法。

  而对此非静态成员方法,它访问静态成员方法/变量显然是不用限制的。

  因而,要是说想在不成立对象的情况下调用有些方法,就能够将以此点子设置为static。大家最常见的static方法正是main方法,至于怎么main方法必须是static的,未来就很精晓了。因为程序在实施main方法的时候未有开创任何对象,由此唯有由此类名来访问。

  其它记住,关于构造器是或不是是static方法可参看:

  壹.static最重要字的用途

2)static变量

  static变量也称作静态变量,静态变量和非静态变量的界别是:静态变量被抱有的对象所共享,在内部存款和储蓄器中唯有1个别本,它当且仅当在类初次加载时会被伊始化。而非静态变量是目的所持有的,在创设对象的时候被早先化,存在八个别本,种种对象具有的别本互不影响。

  static成员变量的开端化顺序根据定义的逐一举办开头化。

3)static代码块

  static关键字还有一个比较重大的成效就是用来产生静态代码块以优化程序品质。static块能够放置类中的任什么地点方,类中能够有多个static块。在类初次被加载的时候,会根据static块的一一来施行种种static块,并且只会试行二遍。

  为何说static块能够用来优化程序品质,是因为它的特征:只会在类加载的时候施行一遍。下边看个例证:

class Person{

        private Date birthDate;

        public Person(Date birthDate) {

                this.birthDate = birthDate;

         }

         boolean isBornBoomer() {

                 Date startDate = Date.valueOf(“1946”);

                 Date endDate = Date.valueOf(“1964”);

                 return birthDate.compareTo(startDate)>=0 &&
birthDate.compareTo(endDate) < 0;

          }

}

  isBornBoomer是用来以这个人是或不是是1947-一96伍年降生的,而每趟isBornBoomer被调用的时候,都会生成startDate和birthDate多少个指标,产生了半空中浪费,假若改成那样功效会越来越好:

class Person{

        private Date birthDate;

        private static Date startDate,endDate;

        static{

                startDate = Date.valueOf(“1946”);

                endDate = Date.valueOf(“1964”);

         }

        public Person(Date birthDate) {

                this.birthDate = birthDate;

         }

        boolean isBornBoomer() {

                return birthDate.compareTo(startDate)>=0 &&
birthDate.compareTo(endDate) < 0;

        }

}

从而,多数时候会将部分只必要开始展览3遍的先河化操作都坐落static代码块中张开。

  二.static关键字的误区

二.static关键字的误区

  叁.科学普及的笔试面试题

1.static关键字会改动类中成员的访问权限吗?

  有些初学的意中人会将java中的static与C/C++中的static关键字的效能模糊了。在此地只需求记住一点:与C/C++中的static分化,Java中的static关键字不会潜移默化到变量也许措施的功效域。在Java中能够影响到走访权限的唯有private、public、protected(包蕴包访问权限)那多少个第1字。看上面包车型地铁例子就知晓了:

88bifa必发唯一官网 2

  提醒错误”Person.age
不可视”,那申明static关键字并不会变动变量和格局的走访权限。

  若有不正之处,希望谅解并应接讨论指正。

2.能透过this访问静态成员变量吗?

  就算对于静态方法来讲未有this,那么在非静态方法中可见通过this访问静态成员变量吗?先看上面包车型客车3个例证,这段代码输出的结果是怎样?

public class Main {

        static int value = 33;

        public static void main(String[] args) throws Exception{

                new Main().printValue();

         }

        private void printValue(){

               int value = 3;

                System.out.println(this.value);

        }

88bifa必发唯一官网,33

  那中间主要调查队this和static的精晓。this代表怎样?this代表当前目的,那么通过new
Main()来调用printValue的话,当前目的正是通过new
Main()生成的靶子。而static变量是被对象所享有的,由此在printValue中的this.value的值毫无疑问是33。在printValue方法内部的value是某个变量,根本不恐怕与this关联,所以输出结果是3③。在那边永恒要牢记一点:静态成员变量尽管独自于对象,可是不代表不能透过对象去拜谒,全体的静态方法和静态变量都足以因此对象访问(只要访问权限丰裕)。

  请尊崇小编劳动成果,转发请标明原来的文章链接:

叁.static能成效于某些变量么?

  在C/C++中static是足以成效域局地变量的,可是在Java中切记:static是不允许用来修饰局地变量。不要问为啥,那是Java语法的规定。

  具体原因能够参照他事他说加以调查那篇博文的座谈:

  

三.大面积的笔试面试题

  下边列举部分面试笔试中时时遇上的有关static关键字的主题材料,仅供参谋,如有补充应接下方留言。

1.底下这段代码的出口结果是何等?

public class Test extends Base{

        static{

                System.out.println(“test static”);

        }

        public Test(){

                System.out.println(“test constructor”);

        }

        public static void main(String[] args) {

                new Test();

        }

}

class Base{

        static{

                System.out.println(“base static”);

        }

        public Base(){

                System.out.println(“base constructor”);

        }

}

base static

test static

base constructor

test constructor

  至于为啥是这几个结果,大家先不商讨,先来想转手这段代码具体的实践进度,在执行起来,先要寻觅到main方法,因为main方法是先后的输入,但是在推行main方法此前,必须先加载Test类,而在加载Test类的时候开掘Test类承袭自Base类,由此会转去先加载Base类,在加载Base类的时候,开掘有static块,便推行了static块。在Base类加载成功之后,便一而再加载Test类,然后发掘Test类中也可以有static块,便实践static块。在加载完所需的类之后,便初叶实施main方法。在main方法中实践new
Test()的时候会先调用父类的构造器,然后再调用自己的构造器。由此,便现身了上边包车型地铁输出结果。

二.这段代码的出口结果是如何?

public class Test {

        Person person = new Person(“Test”);

        static{

                System.out.println(“test static”);

        }

        public Test() {

                System.out.println(“test constructor”);

        }

        public static void main(String[] args) {

                new MyClass();

        }

}

class Person{

        static{

                System.out.println(“person static”);

        }

        public Person(String str) {

                System.out.println(“person “+str);

        }

}

class MyClass extends Test {

        Person person = new Person(“MyClass”);

        static{

                System.out.println(“myclass static”);

        }

        public MyClass() {

                System.out.println(“myclass constructor”);

        }

}

test static 

myclass static

person static

person Test

test constructor

person MyClass

myclass constructor

  类似地,大家依然来想转手这段代码的求实实行进程。首先加载Test类,由此会进行Test类中的static块。接着奉行new
MyClass(),而MyClass类还并未有被加载,由此要求加载MyClass类。在加载MyClass类的时候,开采MyClass类承继自Test类,不过由于Test类已经被加载了,所以只要求加载MyClass类,那么就能实行MyClass类的中的static块。在加载完事后,就经过构造器来扭转对象。而在扭转对象的时候,必须先开头化父类的分子变量,由此会推行Test中的Person
person = new
Person(),而Person类还从未被加载过,由此会先加载Person类并进行Person类中的static块,接着实行父类的构造器,完结了父类的开首化,然后就来开始化本身了,由此会随之试行MyClass中的Person
person = new Person(),最后施行MyClass的构造器。

叁.这段代码的输出结果是何等?

public class Test {

        static{

                System.out.println(“test static 1”);

        }

        public static void main(String[] args) {

        }

        static{

                System.out.println(“test static 2”);

        }

}

test static 1

test static 2

  即使在main方法中并未有其余语句,不过依旧会输出,原因上边已经讲述过了。此外,static块能够出现类中的任何地方(只要不是艺术内部,记住,任何方式内部都1贰分),并且执行是依据static块的种种实践的。

正文转发于:http://www.cnblogs.com/dolphin0520/p/3799052.html

一.static重中之重字的用途

  在《Java编制程序观念》P86页有诸如此类1段话:

  “static方法正是未有this的点子。在static方法内部不能够调用非静态方法,反过来是能够的。而且可以在一直不成立任何对象的前提下,仅仅经过类本人来调用static方法。那实际正是static方法的首要用途。”

  这段话尽管只是表明了static方法的特殊之处,可是能够看出static关键字的着力成效,一言以蔽之,一句话来描述正是:

  方便在未曾创立对象的状态下来举行调用(方法/变量)。

  很显著,被static关键字修饰的方式照旧变量无需借助于对象来开始展览走访,只要类被加载了,就足以由此类名去进行访问。

  static能够用来修饰类的分子方法、类的积极分子变量,别的能够编写static代码块来优化程序品质。

1)static方法

  static方法一般称作静态方法,由于静态方法不依据于别的对象就可以举办走访,因而对此静态方法来讲,是尚未this的,因为它不依赖于任何对象,既然都尚未指标,就谈不上this了。并且鉴于那几个特点,在静态方法中不能够访问类的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都以必须信赖具体的目的本领够被调用。

  但是要留心的是,固然在静态方法中不能访问非静态成员方法和非静态成员变量,不过在非静态成员方法中是能够访问静态成员方法/变量的。举个轻松的例子:

88bifa必发唯一官网 3

  在下面的代码中,由于print二方法是独自于对象存在的,能够平素用过类名调用。借使说能够在静态方法中做客非静态方法/变量的话,那么只要在main方法中有上边一条语句:

  MyObject.print2();

  此时目的都未有,str二根本就不设有,所以就能够发生冲突了。同样对于措施也是如出1辙,由于您不能够预言在print壹格局中是还是不是访问了非静态成员变量,所以也禁止在静态成员方法中走访非静态成员方法。

  而对此非静态成员方法,它访问静态成员方法/变量鲜明是绝不限制的。

  由此,即使说想在不创造对象的境况下调用有些方法,就能够将以此法子设置为static。大家最广大的static方法就是main方法,至于何以main方法必须是static的,未来就很驾驭了。因为程序在实践main方法的时候未有开创任何对象,因而唯有由此类名来访问。

  此外记住,关于构造器是或不是是static方法可参看:

2)static变量

  static变量也称作静态变量,静态变量和非静态变量的界别是:静态变量被有着的目的所共享,在内部存款和储蓄器中只有3个别本,它当且仅当在类初次加载时会被开头化。而非静态变量是指标所怀有的,在创立对象的时候被起首化,存在多少个别本,各种对象具备的别本互不影响。

  static成员变量的起首化顺序依据定义的依次实行发轫化。

3)static代码块

  static关键字还有贰个相比主要的法力正是用来产生静态代码块以优化程序品质。static块能够停放类中的任哪个地方方,类中能够有七个static块。在类初次被加载的时候,会依照static块的次第来试行各类static块,并且只会试行2次。

  为什么说static块能够用来优化程序质量,是因为它的表征:只会在类加载的时候执行3遍。下边看个例证:

class Person{
 private Date birthDate;

 public Person(Date birthDate) {
  this.birthDate = birthDate;
 }

 boolean isBornBoomer() {
  Date startDate = Date.valueOf("1946");
  Date endDate = Date.valueOf("1964");
  return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate) < 0;
 }
}

  isBornBoomer是用来以此人是还是不是是壹玖四陆-一玖陆贰年出生的,而每回isBornBoomer被调用的时候,都会生成startDate和birthDate多少个指标,变成了半空中浪费,假诺改成那样效能会越来越好:

class Person{
 private Date birthDate;
 private static Date startDate,endDate;
 static{
  startDate = Date.valueOf("1946");
  endDate = Date.valueOf("1964");
 }

 public Person(Date birthDate) {
  this.birthDate = birthDate;
 }

 boolean isBornBoomer() {
  return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate) < 0;
 }
}

  由此,许多时候会将部分只需求展开二次的起头化操作都放在static代码块中进行。

二.static关键字的误区

一.static首要字会退换类中成员的走访权限吗?

  有些初学的爱人会将java中的static与C/C++中的static关键字的功效模糊了。在那边只要求记住一点:与C/C++中的static差异,Java中的static关键字不会影响到变量也许措施的成效域。在Java中可见影响到走访权限的唯有private、public、protected(包罗包访问权限)那多少个主要字。看上面包车型客车例证就知晓了:

88bifa必发唯一官网 4

  提醒错误”Person.age
不可视”,这注明static关键字并不会转移变量和方式的拜会权限。

二.能通过this访问静态成员变量吗?

  纵然对于静态方法来讲未有this,那么在非静态方法中可见透过this访问静态成员变量吗?先看上面包车型客车一个例证,这段代码输出的结果是怎么着?

public class Main {  
 static int value = 33; 

 public static void main(String[] args) throws Exception{
  new Main().printValue();
 }

 private void printValue(){
  int value = 3;
  System.out.println(this.value);
 }
}

 

88bifa必发唯一官网 588bifa必发唯一官网 6

33

View Code

  这之中根本考查队this和static的知晓。this代表怎样?this代表当前指标,那么通过new
Main()来调用printValue的话,当前指标就是经过new
Main()生成的靶子。而static变量是被对象所怀有的,由此在printValue中的this.value的值毫无疑问是3三。在printValue方法内部的value是一对变量,根本不容许与this关联,所以输出结果是3三。在那边永恒要牢记一点:静态成员变量固然独自于对象,不过不意味着不得以因而对象去访问,全部的静态方法和静态变量都足以通过对象访问(只要访问权限丰裕)。

三.static能成效于一些变量么?

  在C/C++中static是足以功能域局地变量的,可是在Java中切记:static是不容许用来修饰局地变量。不要问怎么,那是Java语法的规定。

  具体原因能够参考那篇博文的批评:

三.广阔的笔试面试题

  下面列举部分面试笔试中平时遇上的有关static关键字的主题素材,仅供参谋,如有补充招待下方留言。

壹.底下这段代码的出口结果是哪些?

public class Test extends Base{

 static{
  System.out.println("test static");
 }

 public Test(){
  System.out.println("test constructor");
 }

 public static void main(String[] args) {
  new Test();
 }
}

class Base{

 static{
  System.out.println("base static");
 }

 public Base(){
  System.out.println("base constructor");
 }
}

88bifa必发唯一官网 788bifa必发唯一官网 8

base static
test static
base constructor
test constructor

View Code

  至于为什么是这些结果,大家先不商讨,先来想转手这段代码具体的进行进程,在奉行起来,先要搜索到main方法,因为main方法是先后的输入,可是在实践main方法在此之前,必须先加载Test类,而在加载Test类的时候开采Test类承接自Base类,由此会转去先加载Base类,在加载Base类的时候,开掘有static块,便施行了static块。在Base类加载成功之后,便延续加载Test类,然后开掘Test类中也是有static块,便实践static块。在加载完所需的类之后,便早先举行main方法。在main方法中执行new
Test()的时候会先调用父类的构造器,然后再调用本人的构造器。因而,便出现了上面包车型大巴输出结果。

二.这段代码的出口结果是怎么样?

public class Test {
 Person person = new Person("Test");
 static{
  System.out.println("test static");
 }

 public Test() {
  System.out.println("test constructor");
 }

 public static void main(String[] args) {
  new MyClass();
 }
}

class Person{
 static{
  System.out.println("person static");
 }
 public Person(String str) {
  System.out.println("person "+str);
 }
}


class MyClass extends Test {
 Person person = new Person("MyClass");
 static{
  System.out.println("myclass static");
 }

 public MyClass() {
  System.out.println("myclass constructor");
 }
}

88bifa必发唯一官网 988bifa必发唯一官网 10

test static
myclass static
person static
person Test
test constructor
person MyClass
myclass constructor

View Code

  类似地,咱们仍旧来想转手这段代码的切切实实实行进度。首先加载Test类,因此会施行Test类中的static块。接着施行new
MyClass(),而MyClass类还一直不被加载,由此须求加载MyClass类。在加载MyClass类的时候,开采MyClass类承袭自Test类,不过出于Test类已经被加载了,所以只必要加载MyClass类,那么就能推行MyClass类的中的static块。在加载完今后,就由此构造器来扭转对象。而在转移对象的时候,必须先开始化父类的积极分子变量,由此会试行Test中的Person
person = new
Person(),而Person类还尚无被加载过,因而会先加载Person类并实践Person类中的static块,接着实行父类的构造器,完结了父类的开始化,然后就来开始化自个儿了,因而会跟着实践MyClass中的Person
person = new Person(),最终实行MyClass的构造器。

3.这段代码的出口结果是怎么着?

public class Test {

 static{
  System.out.println("test static 1");
 }
 public static void main(String[] args) {

 }

 static{
  System.out.println("test static 2");
 }
}

88bifa必发唯一官网 1188bifa必发唯一官网 12

test static 1
test static 2

View Code

  尽管在main方法中绝非其余语句,可是依然会输出,原因上边已经讲述过了。此外,static块可以出现类中的任哪个地点方(只要不是办法内部,记住,任何格局内部都不行),并且实行是依据static块的依次实施的。

  参谋资料:

  

  

  

  

  

  

  

  《Java编制程序观念》