Java基础进阶_day04_(static,代码块,final,包与权限修饰符,内部类)

本文详细讲解了Java中的static关键字,包括静态成员变量和普通成员变量的区别;代码块的分类和执行顺序;final关键字的作用及其修饰变量的初始化;包的概念、命名、定义和import关键字的使用;以及权限修饰符的种类和应用。此外,还介绍了内部类的分类、成员访问特点、静态成员内部类、局部内部类和匿名内部类的应用案例。
摘要由CSDN通过智能技术生成

Java基础进阶_day04_(static,代码块,final,包与权限修饰符,内部类)

1. static关键字

# 特点:静态的意思, 可以修饰成员变量和成员方法.
  * 随着类的加载而加载;
  * 优先于对象存在;
  * 被类的所有对象共享(可通过对象名调用);
  * 可以通过类名调用(也可以通过对象名调用);
  * 静态修饰成员是类成员,一般通过类名调用.
1.1 注意事项
# 注意事项: 静态成员只能访问静态成员(后加载的可以访问先加载的成员,先加载的不能访问后加载的)
  * 在静态方法中没有this和super关键字(this是代表当前对象的引用,super是父类在this代表的对象中存储空间的标识,静态是先于对象存在的);
  * 静态方法只能访问静态的成员变量和静态的成员方法, 静态成员是随着类的加载而存在的,非静态的成员在创建对象才存在;
  * 非静态的成员方法可以调用静态的成员(对象创建后,类的静态成员已经加载完毕);
  * static修饰的成员变量一般在定义时就给出初始值.
1.2 静态成员变量和普通成员变量的区别
# 所属不同:
  * 静态变量是属于类(类变量);
  * 成员变量是属于对象的;
# 内存中位置不同:
  * 静态变量是在方法区的静态区;
  * 成员变量在堆内存中;
# 在内存中出现的时间不同:
  * 静态变量是随着类的加载而加载,随着类的消失而消失;
  * 成员变量是随着对象的创建而存在,随着对象的消失而消失;
# 调用方式不同:
  * 静态成员可以通过类名和对象名直接调用;
  * 成员变量只能通过对象名调用.
1.3 案例代码
public class MySaticDemo {
    public static void main(String[] args) {
        // 优先于对象存在,可以通过类名调用(也可以通过对象名调用)
        System.out.println(StaticDemo.num1);
        StaticDemo s = new StaticDemo();
        System.out.println(s.num1);
    }
}
// static关键字案例
class StaticDemo {
    int num = 10;
    // 静态成员变量
    static int num1 = 20;
    public StaticDemo() {
    }
    public StaticDemo(int num) {
        this.num = num;
    }
    // 静态成员方法
    public static void show() {
        // 静态方法只能访问静态的成员变量和静态的成员方法
        //num = 20;报错
        //this.num = 20;报错
    }
    // 静态成员方法
    public static void show2() {
        // 静态方法能访问静态方法
        StaticDemo.show();
        // 静态方法不能访问非静态的成员
        //num = 30;报错
        //show3();报错
    }
    // 成员方法
    public void show3() {
        // 非静态能直接访问静态成员
        num1 = 20;
        show();
    }
}

2. 代码块

代码块:在Java程序中使用{}括起来的代码称为代码块.

2.1 代码块分类
# 代码块的分类:根据在Java程序中位置不同分类.
  * 局部代码块:定义在局部位置,用于限定变量的生命周期;
  * 构造代码块:定义在类中的成员位置的代码块,每次调用构造方法前,均会先执行构造代码块, 可以将构造方法中相同的代码放到构造代码块,进行创建对象时数据的初始化;
  * 静态代码块:在成员位置使用static修饰的代码块.
2.2 代码块特点
# 局部代码块:随着方法的调用而执行,在局部位置用于限定局部变量的声明周期;
# 构造代码块:随着创建对象而执行,每次创建对象均会执行,构造方法间相互调用时,代码块只会执行一次;
# 静态代码块:随着类的加载而执行,只执行一次(不管该对象被创建多少次只执行一次).
2.3 静态代码块,构造代码块,构造方法的执行顺序
(先后顺序)静态代码块-->构造代码块-->构造方法.
2.4 案例代码
/*
 * 代码块测试
 */
public class CodeBlockDemo {
    public static void main(String[] args) {
        Person p1 = new Person();
        p1.show();
        System.out.println("------------");
        Person p2 = new Person();
        p2.show();
        /*
         * 输出结果:
         * 静态代码块1
         * 静态代码块2
         * 构造代码块1
         * 构造代码块2
         * 局部代码块1
         * 局部代码块2
         * ------------
         * 构造代码块1
         * 构造代码块2
         * 局部代码块1
         * 局部代码块2
         */
        Person p3 = new Person(12);
        p3.show();
        System.out.println("------------");
        Student s = new Student();
        /*
         * 输出结果:
         * 构造代码块1
         * 构造代码块2
         * 局部代码块1
         */
    }
}
class Person {
    private int age;
    static { 
        System.out.println("静态代码块1");
    }
    { 
        System.out.println("构造代码块1");
    }
    public Person() {
        {
            System.out.println("局部代码块1");
        }
    }
    public Person(int age) {
        this();
        this.age = age;
    }
    { 
        System.out.println("构造代码块2");
    }
    public void show() {
        {
            System.out.println("局部代码块2");
        }
    }
    static { 
        System.out.println("静态代码块2");
    }
}
class Student extends Person {

    public Student() {
        super();
    }
}

3. final关键字

final关键字:最终的意思.

3.1 final关键字特点
# 特点: 可以修饰类,方法,变量
  * 修饰类:修饰的类是最终类,不能被继承;
  * 修饰方法:修饰的方法不能被重写(子类不能出现和该方法同名的方法), 修饰类的构造方法,该构造方法不能被调用,如果所有的构造方法都被final修饰,该类不能被创建对象;
  * 修饰变量:修饰的变量不能被重新赋值(基本数据类型是数值,引用类型时是地址值不能改变(其指向的堆内存中的值可以改变)).
3.2 final关键字修饰的变量的初始化
# final修饰的变量只能赋值一次;
# final修饰的变量(非静态)在构造方法执行完之前赋值(构造方法中,构造代码块中).
3.3 案例代码
public class MyFinalDemo {
    public static void main(String[] args) {
        // 修饰基本数据类型的变量
        final int num = 10;
        // 修饰的变量不能被重新赋值
        //num = 20;
        // 修饰引用类型的变量,是地址值不能变化
        final Student s = new Student();
        // s指向的堆内存中的成员的值可以修改
        s.age = 23;
    }
}
class Student {
    int age;
}

4. 包与权限修饰符

4.1 包

包: 本质是文件夹, 用来对类进行分类管理.

4.1.1 包的命名
# 按照类的功能分;
# 按照项目的模块分.
4.1.2 包的定义
# 格式:package 包名;
  * 多级包使用.隔开
4.1.3 注意事项
# package语句必须是程序的第一条有效语句;
# 一个Java文件中只能有一个;
# 如果没有package语句,默认是无包名.
4.1.4 import关键字
# import关键字:用哪个类就导入那个Java文件,不用.*方式.
  * 导包格式1: import 包名.java文件;
  * 导包格式2: import 包名.
# 注意事项:当多个包中相同的类名时,只能有一个类导包,其他的包下同名的类使用全类名使用.
4.2 修饰符
4.2.1 权限修饰符

权限修饰符(四种):四种权限修饰符在任意时刻只能出现一种.

修饰符本类中同包(子类和无关类)不同包下子类不同包下无关类
publicYYYY
protectedYYY
默认YY
privateY
4.2.2 抽象修饰符
# 抽象修饰符:abstract
4.2.3 状态修饰符
# 状态修饰符:static final
4.2.4 修饰符的使用
# 修饰类:一般使用public
    权限修饰符:public 默认
    状态修饰符:final
    抽象修饰符:abstract
# 修饰成员方法:一般使用public
    权限修饰符:public protected 默认 private
    状态修饰符:final
    抽象修饰符:abstract
    常用一下几个:
    public static 
    public final 
    public abstract
# 修饰成员变量:一般使用private
    权限修饰符:public protected 默认 private
    状态修饰符:final
    常用:public static final
# 修饰构造方法:一般使用public
    权限修饰符:public,默认,protected,private

5. 内部类

概念: 将类定义在其他类的内部.内部类和外部类没有继承关系.

5.1 内部类分类
# 内部类的位置:
  * 成员位置:在类成员位置定义的内部类,成员内部类;
  * 局部位置:在局部位置定义的内部类,局部内部类;
5.2 内部类成员访问特点
# 内部类可以直接访问外部类的成员,包括私有的,当内部类的变量名和外部类的成员变量名相同时, 可以通过外部类名进行限定this来访问外部成员[outer.this代表外部类的this];
# 外部类要访问内部类成员必须要创建对象(成员内部类相当于是成员,只有创建类的对象才能访问类的成员);
5.3 成员内部类
# 成员内部类: 相当于是成员方法(创建外部类后才能创建内部类)
  * 访问格式:外部类名.内部类名  对象名=外部类对象.内部类对象;
        Outer.Inner oi = new Outer().new Inner();
  * 成员内部类的修饰符:
        一般使用private修饰,保证了数据安全,使用提供公共的访问的方法进行控制(和成员变量类似).
5.4 静态成员内部类
# 静态成员内部类:(内部类可看作是成员方法,则可以使用static修饰),方便数据的访问.
  * 访问的外部类的成员必须是静态成员;
  * 访问方式:不能通过普通成员内部类的访问方式进行访问.
        Outer.Inner oi = new Outer.Inner();
5.5 局部内部类
# 局部内部类:定义方法中的类(在该局部位置创建对象并调用内部类方法,外部类通过调用该成员方法去访问内部类).
  * 可以直接访问外部类的成员;
  * 在局部位置可以创建内部类对象,通过创建外部类的对象并调用该成员方法来调用内部类方法;
  * 局部内部类访问局部变量:局部变量必须是final修饰的常量(局部变量是随着方法的调用而存在,随着方法的弹栈而消失, 而内部类是在堆内存中,不会立即消失,为了安全,则该局部变量必须是常量, 常量是在常量池中,方法弹栈后还能继续供内部类使用).
5.6 匿名内部类
# 匿名内部类:没有名字的局部内部类(就是内部类的简化写法).
  * 前提:存在一个类(具体类或抽象类)或接口.
  * 格式(在方法内部):
    new 类名或接口名(){
        重写类或接口中的方法;
    };
  * 本质:是一个继承了该类或者实现了该接口的子类匿名对象.
5.7 案例代码
/*
 * 内部类案例
 */
public class InnerClassDemo {
    public static void main(String[] args) {
        // 外部类访问成员内部类,
        // 只能创建对象才能访问,内部类是外部类的一部分,需要使用外部类类名调用内部类
        Outer.Inner1 outer_inner = new Outer().new Inner1();
        outer_inner.show();
        // 私有成员内部类,提供方法的访问方式
        Outer outer = new Outer();
        outer.method("教师");
        // 外部类访问静态成员内部类,静态内部访问方式和静态成员方法相似
        Outer.Inner3 outer_inner3 = new Outer.Inner3();
        outer_inner3.show();
        // 外部类访问局部内部类,通过在局部位置创建内部类的对象进行访问
        Outer outer4 = new Outer();
        outer4.method2();
        // 使用匿名内部类(接口)
        // 使用匿名类方式1
        new Inner4() {
            @Override
            public void show() {
                System.out.println("show null");
            }
        }.show();
        // 使用匿名类方式2
        Inner4 i4 = new Inner4() {
            @Override
            public void show() {
                System.out.println("show i4");
            }
        };
        i4.show();
        // 使用匿名内部类(具体类)
        // 只有这一种使用方式,实际上是继承后进行方法的重写
        new Inner5() {
            public void show(){
                System.out.println("show Inner5");
            };
        }.show();
        // 使用匿名内部类(抽象类)
        // 使用匿名类方式1
        new Inner6() {
            @Override
            public void show() {
                System.out.println("show Inner5");
            }
        }.show();
        // 使用匿名类方式1
        Inner6 i6 = new Inner6() {
            @Override
            public void show() {
                System.out.println("show Inner5");
            }
        };
    }
}
// 定义外部类
class Outer {
    // 定义成员变量
    private int num1 = 10;
    public int num2 = 20;
    public int num3 = 30;
    public static int num4 = 60;
    public void show() {
        System.out.println("outer show");
    }
    // 定义成员内部类
    class Inner1 {
        int num3 = 40;
        public void show() {
            int num3 = 50;
            // 内部类可以访问外部类的私有成员变量
            System.out.println(num1);
            // 内部类可以访问外部类的成员变量
            System.out.println(num2);
            // 内部类可以访问外部类的成员方法
            Outer.this.show();

            System.out.println(num3);   // 访问局部变量
            System.out.println(this.num3);  // 访问内部类的成员变量
            System.out.println(Outer.this.num3);// 访问外部类的成员变量,使用类名进行限定this的标识
        }
    }
    // 私有成员内部类,提供方法的访问方式,相当于是私有化成员变量
    // 可以对控制对此内部类的访问
    private class Inner2 {
        public void show() {
            System.out.println("此处内容只有老师才能看到");
        }
    }
    public void method(String type) {
        if(type.equals("教师")) {
            Inner2 i2 = new Inner2();
            i2.show();
        }
    }
    // 定义静态成员内部类,随着类的加载而加载
    static class Inner3 {
        public void show() {
            // 静态内部类只能访问外部类的静态成员
            //System.out.println(num1);
            System.out.println(num4);
        }
    }
    // 定义局部内部类
    public void method2() {
        int num5 = 70;
        final int num6 = 80;
        class Inner4 {
            public void show() {
                // 局部内部类可以访问外部类的成员
                System.out.println(num1);
                System.out.println(num4);
                Outer.this.show();
                // 局部内部类只能访问被final修饰的局部变量即常量
                //System.out.println(num5);报错
                System.out.println(num6);
            }
        }
        // 通过在局部位置创建内部类的对象进行访问
        Inner4 i4 = new Inner4();
        i4.show();
    }
}
// 定义一个接口,匿名内部类用
interface Inner4 {
    public abstract void show();
}
// 定义一个具体类,匿名内部类用
class Inner5 {
    public void show(){};
}
// 定义一个具体类,匿名内部类用
abstract class Inner6 {
    public abstract void show();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值