关键字final和static用法

目录

 

1.final

1.1修饰类

1.2修饰方法

1.3修饰方法

1.4修饰变量

2.static

2.1修饰成员变量

2.2修饰方法

2.3静态代码块

2.4修饰内部类

2.5static导入包

2.6static例子

2.6.1静态代码块

 2.6.2静态代码块和构造函数

2.6.3  面试题(继承、静态代码块、构造函数、成员变量)

2.6.4static代码块多个按照顺序执行


 

1.final

主要用法有以下四种:

  1. 用来修饰数据:变量只能被赋值一次且它的值无法被改变。对于成员变量来讲,我们必须在声明时或者构造方法中对它赋值;

  2. 用来修饰方法参数:在变量的生存期中它的值不能被改变;

  3. 修饰方法:该方法无法被重写;(不常用)

  4. 修饰类:该类无法被继承extends。(不常用)

1.1修饰类

以下代码编译器直接报错

package finalstudy;

/**
 * @author yuguang
 * @date 2021/2/3 10:24
 * @description
 * todo final修饰类无法被继承
 */
public class TestFinal01 {

    public static void main(String[] args) {
        ManPeople man = new ManPeople();
        System.out.println(man.getAge());
    }
}

class ManPeople extends People {

}

final class People{
    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

1.2修饰方法

编译器报错

package finalstudy;

/**
 * @author yuguang
 * @date 2021/2/3 10:24
 * @description todo final修饰方法无法被重写override
 */
public class TestFinal02 {

    public static void main(String[] args) {
        People man1 = new ManPeople();
        System.out.println(man1.getNameAndAge());

        ManPeople man = new ManPeople();
        man.setAge(18);
        man.setName("xixi");
        System.out.println(man.getNameAndAge());
    }
}

class ManPeople extends People {

    @Override
    public String getNameAndAge() {
        return "不想告诉你";
    }
}

class People {
    private String name;
    private int age;

    public final String getNameAndAge() {
        return name + " : " + age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

1.3修饰方法

编译器报错代码

package finalstudy;

/**
 * @author yuguang
 * @date 2021/2/3 10:24
 * @description todo final修饰方法无法被重写,编译器直接报错
 */
public class TestFinal03 {

    public static void main(String[] args) {

        int age = 1;

        System.out.println(age++);

        System.out.println(++age);
        People man1 = new ManPeople();
        System.out.println(man1.getNameAndAge());

        ManPeople man = new ManPeople();
        man.setAge(18);
        man.setName("xixi");
        System.out.println(man.getNameAndAge());

        System.out.println(man.testFinal(18, "xixi"));
    }
}

class ManPeople extends People {

    @Override
    public String getNameAndAge() {
        return "不想告诉你";
    }
}

class People {
    private String name;
    private int age;

    public String testFinal(final int age, final String name) {
        name = "不告诉你";
        age = 18;
        return name + " : " + age;
    }

    //重载
    public String testFinal(final String name, final int age) {
        return name + " : " + age;
    }

    public String getNameAndAge() {
        return name + " : " + age;
    }

    //重载
    public final String getNameAndAge(String name) {
        return name + " : " + age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

1.4修饰变量

package finalstudy;

/**
 * @author yuguang
 * @date 2021/2/3 10:24
 * @description 
 * 包括成员变量和局部变量,该变量只能被赋值一次且它的值无法被改变。
 * 对于成员变量来讲,我们必须在声明时或者构造方法中对它赋值;
 */
public class TestFinal04 {
    private final String name = null;

    private final int age;

    public TestFinal04() {
        age = 0;
    }


    public static void main(String[] args) {
        //变量只能被赋值一次且它的值无法被改变
        final int age;
        age = 18;
        System.out.println(age);
//        age = 19; //报错

    }
}

 

2.static

引入地址(https://www.cnblogs.com/adeng/p/6971366.html

java中static关键字主要有两种作用:

第一:为某特定数据类型或对象分配单一的存储空间,而与创建对象的个数无关。

第二,实现某个方法或属性与类而不是对象关联在一起。

简单来说,在java语言中,static主要有5中使用情况:成员变量、成员方法、代码块,内部类和静态导包。

基本用法:

  1. static修饰成员变量:该成员变量属于类变量,可以通过 ClassName.attributeName 直接引用,而不需要new出类的实例。
  2. static修饰成员方法:该方法属于类的方法,可以通过 ClassName.methodName 直接引用,而不需要new出类的实例。
  3. static修饰代码块:仅在类初始化的时候执行一次,且加载顺序是严格按照类中静态资源的定义顺序来加载的;静态代码块对于定义在它之后的静态变量,可以赋值,但是不能访问。;父类代码块->子类代码块。
  4. static修饰内部类:static不能修饰普通类,只能修饰内部类,被static修饰的内部类的创建方式: new OuterClass.InnerClass()。
  5. static导入包:语法“import static java.lang.Math.*”,这样在类中就可以直接使用Math类中的静态方法而不需要写类名,个人认为,在频繁使用某个类的时候比较方便,但是降低了可读性。并且不建议导入*

2.1修饰成员变量

public class TestStatic02 {
 
    public static void main(String[] args) {
        System.out.println(People.description);
        People.printDescription();
    }

}

class People {
    public static String description = "人";

    public static void printDescription() {
        System.out.println("输出介绍: "+description);
    }
}

2.2修饰方法

public class TestStatic02 {
   

    public static void main(String[] args) {
 

        System.out.println(People.description);
        People.printDescription();
    }

}

class People {
    public static String description = "人";

    public static void printDescription() {
        System.out.println("输出介绍: "+description);
    }
}

2.3静态代码块

package study_static;

//初始化的顺序 静态代码块 > 构造代码块 > 构造函数
// 只需要进行一次的初始化操作都放在static代码块中进行。
public class TestStatic03 {


    public static void main(String[] args) {
        PersonWithStatic withStatic = new PersonWithStatic();
        withStatic.setSexType(1);
        System.out.println(withStatic.getSexText());

        PersonNoStatic noStatic = new PersonNoStatic();
        noStatic.setSexType(2);
        System.out.println(noStatic.getSexText());

    }

}


class PersonWithStatic {
    private String sexText;
    private Integer sexType;

    //常量
    private static String woman;
    private static String man;

    static {
        man = "男";
        woman = "女";
    }

    public String getSexText() {
        if (sexType == 1) {
            sexText = woman;
        } else {
            sexText = man;
        }
        return sexText;
    }


    public Integer getSexType() {
        return sexType;
    }

    public void setSexType(Integer sexType) {
        this.sexType = sexType;
    }

    public static String getWoman() {
        return woman;
    }

    public static void setWoman(String woman) {
        PersonWithStatic.woman = woman;
    }

    public static String getMan() {
        return man;
    }

    public static void setMan(String man) {
        PersonWithStatic.man = man;
    }
}


class PersonNoStatic {
    private String sexText;
    private Integer sexType;

    private static String woman = "女";
    private static String man = "男";

    public String getSexText() {
        if (sexType == 1) {
            sexText = woman;
        } else {
            sexText = man;
        }
        return sexText;
    }


    public void setSexText(String sexText) {
        this.sexText = sexText;
    }

    public Integer getSexType() {
        return sexType;
    }

    public void setSexType(Integer sexType) {
        this.sexType = sexType;
    }

    public static String getWoman() {
        return woman;
    }

    public static void setWoman(String woman) {
        PersonNoStatic.woman = woman;
    }

    public static String getMan() {
        return man;
    }

    public static void setMan(String man) {
        PersonNoStatic.man = man;
    }
}

 

2.4修饰内部类

static一般用来修饰成员变量或函数也修饰代码块,一般不能修饰类,只有内部类才可以,被修饰的内部类可以直接作为一个普通类来用,不需要创建一个外部类的实例,而普通内部类的引用需要创建一个外部类的实例。

package study_static;

public class TestStatic05 {

    public static void main(String[] args) {

        //非静态内部类需创建一个父类的实例,方能new
        TestStatic05 father = new TestStatic05();
        Inner inner = father.new Inner();
        inner.print();

        //静态内部类可以直接new
        InnerStatic innerStatic = new InnerStatic();
        innerStatic.print();
    }

    class Inner {

        public void print() {
            System.out.println("Inner");
        }
    }

    static class InnerStatic {
        public static void print() {
            System.out.println("InnerStatic");
        }
    }
}

class Inner1 {

}

 

 

 

2.5static导入包

 

package study_static;


import static java.lang.Math.random;
import static java.lang.System.out;
  
/**
 * @author yuguang
 * @date 2021/2/4 9:28
 * @description static 导入包
 */
public class TestStatic06 {
    

    public static void main(String[] args) {

        double random = Math.random();
        out.println((int) (random * 10000));

        //直接引入Math下面static方法
        out.println(random());

        out.println(random());

 
    }
}

 

2.6static例子

2.6.1静态代码块

 


 
public class TestStatic04 {


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

        Class<?> aClass = Class.forName("study_static.People1");
 
//        System.out.println(People1.description);
//        People1.printDescription();
    }

}

class People1 {
    //静态代码块
    static {
        System.out.println("People1 init ,static code");
    }

    //静态变量
    public static String description = "人";

    //静态方法
    public static void printDescription() {
        System.out.println("输出介绍: "+description);
    }

    //空构造方法
    public People1() {
        System.out.println("constructor");
    }
}

 2.6.2静态代码块和构造函数

静态代码块中:父>子

等级:    静态代码块>构造函数

package study_static;

public class demo2 extends Base {

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

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

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

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

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

2.6.3  面试题(继承、静态代码块、构造函数、成员变量)

在一个类中: 静态代码块  > 成员变量 > 构造函数

父 > 子:如父的 静态代码块、成员变量、构造函数   大于子的

package study_static;

/**
 *  类似地,我们还是来想一下这段代码的具体执行过程。首
 * 1-先加载Test类,因此会执行Test类中的static块。
 * 2-接着执行new MyClass(),而MyClass类还没有被加载,因此需要加载MyClass类。在加载MyClass类的时候,
 * 发现MyClass类继承自Test类,但是由于Test类已经被加载了,所以只需要加载MyClass类,那么就会执行MyClass类的中的static块。
 * 在加载完之后,就通过构造器来生成对象。而在生成对象的时候,
 * 3---必须先初始化父类的成员变量,因此会执行Test中的Person person = new Person(),
 * 而Person类还没有被加载过,因此会先加载Person类并执行Person类中的static块,接着执行父类的构造器,完成了父类的初始化,
 * 然后就来初始化自身了,因此会接着执行MyClass中的Person person = new Person(),最后执行MyClass的构造器。
 */
//todo 静态代码块存在内存中只加载一次
public class Test {
    Person person = new Person("---4---Test");

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

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

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

class MyClass extends Test {
    Person person = new Person("----6----MyClass");

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

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

class Person {
    static {
        System.out.println("3----person static");
    }

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

2.6.4static代码块多个按照顺序执行

public class demo3 {

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

    }

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

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

参考资料:

https://www.cnblogs.com/tonyluis/p/5582529.html

https://www.cnblogs.com/dolphin0520/p/3799052.html

https://www.cnblogs.com/dolphin0520/p/3799052.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值