现在的位置: 首页 > 综合 > 正文

12、static与final关键字详解

2018年05月26日 ⁄ 综合 ⁄ 共 4249字 ⁄ 字号 评论关闭

1、static关键字:可以用于修饰属性,也可以用于修饰方法,还可以用于修饰类。

      satic修饰属性:无论一个类生成了多少个对象,所有这些对象共同使用唯一一份静态的成员变量,;一个对象对给静态成员变量进行了修改,其他对象的该静态成员变量的值也会随之发生变化。如果一个成员变量是static的,那么我们可以通过类名.成员变量名的方式来使用它(推荐使用)。

public
class
StaticTest

{

    public
static void
main(String[] args)

    {

        /* 代码一

        MyStatic ms = new MyStatic();

        MyStatic ms2 = new MyStatic();

  

        ms.a = 10;

  

        System.out.println(ms2.a); //结果为0

        */

        //代码二

        MyStatic ms = new MyStatic();

        MyStatic ms2 = new MyStatic();

  

        ms.a = 10;

  

        System.out.println(ms2.a);

        //结果为10,说明属性被static修饰后,此属性不属于特定的哪个对象

        //而是所有对象共同使用,唯一一份静态的成员变量

  

        //代码三

        MyStatic ms3 = new MyStatic();

  

        MyStatic.a = 12;

            //通过类名.成员变量名的方式来使用它,推荐

  

        System.out.println(ms3.a);//结果为12

    }

}

  

class MyStatic

{

    /*代码一

    int a;

    */

    //代码二

    static
int a;

}

 

2、static修饰方法:static修饰的方法叫做静态方法。对于静态方法来说,可以使用类名.方法名的方式来访问,并且推荐使用这种使用方法

public class StaticTest2
{
 public static void main(String[] args)
 {
  //MyStatic1 t = new MyStatic1();
  //t.output();

  MyStatic1.output();
  //直接使用类名.方法名的方式,推荐使用
 }
}

class MyStatic1
{
 public static void output()
 {
  System.out.println("output");
 }
}

3、关于静态方法继承的问题。

public class StaticTest3
{
 public static void main(String[] args)
 {
         M m = new N();
         m.output();
  //结果为M,而不是N,需要注意
  //对于static方法,继承只会隐藏父类方法,而不是重写 

  //调用哪个方法主要看引用变量的类型

       N n = new N();

      n.output();//结果为N

class M
{
     public static void output()
 {
     System.out.println("M");
 }
}

class N extends M
{
    public static void output()
 {
      ystem.out.println("N");
 }
}

 

静态方法只能继承,不能重写(override)

4、final关键字:final可以修饰属性、方法、类。

A) final修饰类:当一个类被final所修饰,表示该类是个终态类,不能被继承。

final class Test

{

}

则该Test类不能被继承

class Test1 extends Test错误

B)final修饰方法:当一个方法被fianl所修饰时,表示该方法是一个终态方法,不能被重写(override)

C)fianal修饰属性:当一个属性被final所修饰时,表示该属性不能被改写。

当fianl修饰一个原生数据类型时,表示改原生数据类型的值不能发生变化(比如说不能从10变为20);如果fianl修饰一个引用类型时,表示该引用类型不能再指向其他对象了,但该引用所指向的对象的内容是可以发生变化的。

public class FinalTest
{
        public static void main(String[] args)
 {
       People people = new People();
       people.age = 20; //错误,final类型的属性不能被改变
  
       people.address = new Address();//错误

      //fianl修饰一个引用类型时,表示该引用类型不能再指向其他对象了,这里new Address()表示一个新的对象
       people.address.name = "shanghai";//正确,引用所指向的对象的内容是可以发生变化的

 }
}

class People
{
 final int age = 10;

 final Address address = new Address();
}

class Address
{
 String name = "beijing";
}

 

5、对于final类型的成员变量,一般来说有两种赋初值方式:

A)在声明final类型的成员变量时就赋上初值

B)在声明final类型的成员变量时不赋初值,但在类的所有构造方法中都为其赋上初值

public class FinalTest2
{
 final int a;
}
//上例错误
public class FinalTest2
{
 final int a = 0;
}
//上例正确
public class FinalTest2
{
 final int a;

 public FinalTest2()
 {
  a = 0;
 }
}
//上例正确
public class FinalTest2
{
 final int a;

 public FinalTest2()
 {
  a = 0;
 }

 public FinalTest2(int a)
 {
 
 }
}
//上例错误

6、static代码块:静态代码块

public
class
StaticTest4
{
    public
static void
main(String[] args)
    {
        P p =
new S();
    }
}
  
class
P
{
    static 
    {
        System.out.println("P static");
    }
  
    public
P()
    {
        System.out.println("P constructor");
    }
}
  
class
Q
extends P
{
    static 
    {
        System.out.println(" Q static");
    }
  
    public
Q()
    {
        System.out.println("Q constructor");
    }
}
class
S
extends Q
{
    static 
    {
        System.out.println(" S static");
    }
  
    public
S()
    {
        System.out.println("S constructor");
    }
}

执行结果

P static
 Q static
 S static
P constructor
Q constructor
S constructor

如果主程序是这样的:

new S();

new S();

则结果:

P static
 Q static
 S static
P constructor
Q constructor
S constructor
P constructor
Q constructor
S constructor

总结:1)静态代码块。作用也是完成一些初始化工作。首先执行静态代码块,然后执行构造方法。静态代码块在类被加载的时候执行,而构造方法是在生成对象的时候执行(所以先打印静态代码块数据);想要调用某个类来生成对象,首先需要将类加载到java虚拟机上(jvm),然后由jvm加载这个类来生成对象。

        2)类的静态代码块只会执行一次,是在类被加载的时候执的,因为每个类只会被加载一次,所以静态代码块也只会被执行一次;而构造方法则不然,每次生成一个对象的时候都会调用类的构造方法,所以new一次就会调用构造方法一次。

        3)如果继承体系中既有构造方法,又有静态代码块,那么首先执行最顶层的类的静态代码块,一直

执行到最底层类的静态代码块,然后再去执行最顶层类的构造方法,一直执行到最底层类的构造方法。注意:静态代码块只会执行一次。

7、不能在静态方法中访问非静态成员变量;可以在静态方法中访问静态的成员变量。可以在非静态方法中访问静态的成员变量

public class StaticTest5
{
 public static void main(String[] args)
 {
       W.change();
 }
}

class W
{
 int a = 10;   //如果改成:static int a = 10;则正确

 public static void change()
 {
  a++;   //错误
 }
}

以上代码错误,不能在静态的方法中访问非静态成员变量。

总结:静态的只能访问静态的;非静态的可以访问一切

8、不能在静态方法中使用this关键字。

9、接口中所声明的方法都是抽象方法。接口中的方法都是public的;接口中也可以定义成员变量。接口中的成员变量都是public、final、static的

public interface Interface1

{

    int a = 1;   //相当于public final static int a = 1;

}

10、一个类不能既是final又是abstract的。因为abstract的主要目的是定义一种约定,让子类去实现这种约定,而final表示该类不能被继承,这样abstract希望该类可以被继承而final明确说明该类不能被继承,两者矛盾。因此一个类不能既是final的又是abstract的

 

 

 

抱歉!评论已关闭.