12、static与final关键字详解

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的

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值