12、static与final关键字详解

来源:互联网 发布:无尽之剑3宝石数据修改 编辑:程序博客网 时间:2024/05/01 09:02
1、static关键字:可以用于修饰属性,也可以用于修饰方法,还可以用于修饰类。

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

public class StaticTest

{

    publicstaticvoid 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;

    */

    //代码二

    staticinta;

}

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
{
    publicstaticvoid main(String[] args)
    {
        P p =new S();
    }
}
class P
{
    static
    {
        System.out.println("P static");
    }
    publicP()
    {
        System.out.println("P constructor");
    }
}
class Q extends P
{
    static
    {
        System.out.println(" Q static");
    }
    publicQ()
    {
        System.out.println("Q constructor");
    }
}
class S extends Q
{
    static
    {
        System.out.println(" S static");
    }
    publicS()
    {
        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的

0 0