• JavaSE基础day09final、内部类、静态代码块、包、权限修饰符、匿名内部类



    一. 代码块(了解)

    (一)概述

    1、使用大括号包起来的一段代码。放在不同的位置,有不同的名称,有不同的作用,有不同的执行时机。

    2、分类:

           局部代码块

           构造代码块

           静态代码块

           同步代码块(多线程)

    (二)局部代码块

    1、位置:定义在方法中的代码块

    2、作用:

           限定变量的生命周期

           在局部代码块中【声明】的变量,只能在局部代码块的范围内使用,一旦出了局部代码块的大括号,变量就不能继续使用了。

           缩短局部变量的生命周期,及时的释放内存空间提升代码的运行效率

    3、注意事项:

    (1) 代码块可以使用外部的所有资源

    (2) 如果是在局部代码块中修改了局部代码块外声明的变量,局部代码块结束之后,并不会消除局部代码块对这个变量的修改。

    public class Demo01_局部代码块 {
        public static void main(String[] args) {
            int i = 10;
            // 局部代码块: 作用, 限定 定义在局部代码块中变量作用范围
            // 优势: 不仅仅是范围的限定,也是变量在内存中存储时间的限定,例如y变量,如果局部代码块执行完毕, y就变成了一个无法再使用的变量,很快就会被JVM回收掉
            {
                int y = 20;
                System.out.println(y);
                // 如果是局部代码块之外变量使用,不受局部代码块限制
                i = 88;
            }
            // System.out.println(y);
            System.out.println(i);// 88
        }
    }

    (三)构造代码块

    1、位置:定义在类中方法外【成员变量位置】

    2、作用:

    (1) 创建对象的时候给对象的属性值显性赋值

    (2) 提取本类构造方法中的共性内容实现

    3、构造代码块的执行说明:

           1、在创建对象的时候执行,由jvm默认调用

           2、在构造方法执行之前,执行

    public class Demo02_构造代码块 {
        int i = 10;
        String name;
        // 构造代码块:
        // 运行时机: 当每次创建对象的同时, JVM虚拟机主动调用构造代码块一次, 并且是在构造方法之前
        // 作用: 可以给当前对象中的成员变量进行赋值; 如果当前类型中有多个构造方法, 并且这些构造中有相同的处理逻辑
        // 这些逻辑可以提升到构造代码块中完成
        {
            name = "张三";
            System.out.println("构造代码块运行了");
            System.out.println("我是构造方法");
        }
    
        public Demo02_构造代码块(){
           // System.out.println("我是构造方法");
        }
    
        public Demo02_构造代码块(int i){
            this.i = i;
           // System.out.println("我是构造方法");
        }
    
        public static void main(String[] args) {
            Demo02_构造代码块 demo = new Demo02_构造代码块();
            System.out.println(demo.name);
            Demo02_构造代码块 demo1 = new Demo02_构造代码块(99);
        }
    }

    (四)静态代码块(一定掌握)

    1、格式:

           static {

                静态代码块的内容

            }

    2、位置:类中方法外

    3、作用:

    (1) 给类的静态变量赋值

    (2) 用来加载只需要加载一次的资源【例如: 加载数据库驱动】

    4、执行特点:

    (1) 随着类的加载而执行

    (2) 静态代码块只执行一次

    (3) 执行的时机最早:早于所有的对象相关内容

    public class Demo03_静态代码块 {
        int i;
        static int w;
        // 静态代码块:
        // 1. 可以给类型中的静态成员变量进行赋值
        // 2. 静态代码块运行时机: 因为静态都属于类, 因此在当前类进入内存时候(进入方法区),JVM虚拟机主动调用
        // 静态代码块一次
        // 3. 静态代码块使用场景: 如果有代码只需要执行一次, 并且是在所有其他代码运行之前就执行, 那么这些逻辑
        // 可以设计在静态代码块中
        // 举例: 数据库,持久性的存储数据; 需要在交易开始之前, 保证数据库连接成功的(登录数据库,读取数据库登录时用户名和密码)
        // 连接数据库的过程就可以设计在静态代码块中
        static{
           // i = 10;  静态中不能直接使用非静态
           w = 99;
           System.out.println("我是静态代码块");
        }
    
        public static void main(String[] args) {
            System.out.println(Demo03_静态代码块.w);
            Demo03_静态代码块 dmo = new Demo03_静态代码块();
        }
    }

    二. 内部类(了解)

    (一)    概述

    1. 定义在一个类中的另一个类就叫做内部类

      举例:在一个类A的内部定义一个类B,类B就被称为内部类

     

    2. 格式:

      public class Outer { // 外部类

             public class Inner { }// 内部类

      }

     

      人类: 定义成Person, 人类组成很复杂, 身体器官: 心脏, 肝, 肾...

            心脏: 血压, 心跳, 颜色, 控制身体机能

     

    3. 分类: 根据定义的位置不一样以及是否有名分为了不同的内部类,具体分类如下:

      1) 成员内部类

      2) 局部内部类

      3) 匿名内部类(掌握)

     

     

    4. 访问特点:

      内部类可以直接访问外部类的成员,包括私有成员

      外部类要访问内部类的成员,必须创建对象

    (二)    普通成员内部类

    1. 定义位置: 在类中方法外,跟成员变量是一个位置

    1. 外界创建成员内部类格式

    格式:外部类名.内部类名 对象名 = 外部类对象.内部类对象;

    举例:Outer.Inner oi = new Outer().new Inner();

     

    2. 访问方式:

    (1) 内部类可以直接访问外部类的所有成员,包括私有成员

    (2) 外部类访问内部类的成员,必须先创建内部类对象

    public class Body {
        int height = 80;
    
        public void test(){
            System.out.println("我是test");
        }
        // 普通成员内部类
        class Heart{
            String color = "红色";
            int jump = 100;
            int height = 999;
            public void show(){
                // 1. 内部类中可以直接使用外部类中的成员(成员变量, 方法)
               System.out.println(color + "颜色的心脏,每分钟跳" + jump + "下,血压为:" + height
                 + "--" + new Body().height);
                test();
            }
        }
    
        // 2. 外部类如果想使用内部类成员, 需要创建出一个内部类对象
        public void useHeart(){
            System.out.println(height);
            Heart h = new Heart();
            System.out.println(h.color);
            System.out.println(h.jump);
            h.show();
        }
    }
    public class TestInnerClass {
        public static void main(String[] args) {
            // 1. 测试普通成员内部类使用
            Body b = new Body();
            b.useHeart();
    
            System.out.println("--------------------------------");
            // 2. 测试普通成员内部类对象在其他类中创建
            // 外部类名.内部类名  对象名 = new 外部类对象().new 内部类对象();
            Body.Heart h = new Body().new Heart();
            // Heart h1 = new Heart();
            System.out.println(h.color);
            System.out.println(h.jump);
            System.out.println(h.height);
            h.show();
        }
    }

    (三)    私有的成员内部类

    1、也是一个成员内部类,在成员内部类前面加上一个private关键字

    2、访问方式:

      (1) 在外部类以外,不能直接访问外部类中的私有成员内部类

      (2) 可以在外部类中,定义一个访问私有成员内部类的公有方法,让外界可以调用公有方法,间接的访问外部类中的私有成员内部类。

    public class Body1 {
        private int height = 80;
    
        public int getHeight() {
            return height;
        }
    
        public void setHeight(int height) {
            this.height = height;
        }
    
        public void test(){
            System.out.println("我是test");
        }
        // 普通成员内部类
        private class Heart1{
            String color = "红色";
            int jump = 100;
            int height = 999;
            public void show(){
                // 1. 内部类中可以直接使用外部类中的成员(成员变量, 方法)
                System.out.println(color + "颜色的心脏,每分钟跳" + jump + "下,血压为:" + height
                 + "--" + new Body1().height);
                test();
            }
        }
    
        // 2. 外部类如果想使用内部类成员, 需要创建出一个内部类对象
        public void useHeart1(){
            System.out.println(height);
            Heart1 h = new Heart1();
            System.out.println(h.color);
            System.out.println(h.jump);
            h.show();
        }
    }
    public class TestInnerClass {
        public static void main(String[] args) {
            // 3. 测试私有成员内部类: 通过间接方式访问私有成员内部类
            Body1 b1 = new Body1();
            b1.useHeart1();
        }
    }

    (四)    静态的成员内部类

    1、也是一个成员内部类,在成员内部类前面加上一个static关键字

    2、访问方式:

    (1) 成员内部类是外部类的静态成员,所以可以通过外部类名.内部类名的方式直接访问,而不需要创建外部类的对象

    (2) 静态内部类中的非静态成员,需要将所在的内部类对象创建出来之后,才能被调用。

    总结:一个类是否需要创建对象,不取决于该类本身是否是静态,而取决于要访问

                     的成员是否是静态

    3、静态成员内部类的对象创建格式:    

           外部类名.内部类名 内部类对象名 = new 外部类名.内部类名();

    public class Body2 {
        // w表示每天喝多少升水
        static int w = 2;
        // 静态成员内部类
        // 是否需要创建对象调用成员: 如果这个成员是非静态的, 那么创建对象; 如果这个成员是静态成员, 那么不需要创建对象, 类名.直接调用
        static class Shen{
            int day = 1;
            static int wc = 8;
            public void show(){
                System.out.println(day + "天喝了" + w + "升,应该去卫生间"+ wc + "次");
            }
        }
    }
    public class TestInnerClass {
        public static void main(String[] args) {
            // 4. 测试静态成员内部类:
            // 1) 调用静态成员内部类中的静态成员变量
            System.out.println(Body2.Shen.wc);// 8
            // 2) 调用静态成员内部类中非静态成员变量
            // 静态成员内部类对象创建方式:
            // 外部类名.内部类名 对象名 = new 外部类名.内部类名();
            Body2.Shen sh = new Body2.Shen();
            System.out.println(sh.day);// 1
            sh.show();// 1天喝了2升,应该去卫生间8次
        }
    }

    (五)    局部内部类

    1. 定义位置: 局部内部类是定义在方法中的类

    2. 访问方式:

      (1) 局部内部类,外界是无法直接使用,需要在方法内部创建对象并使用

      (2) 该类可以直接访问外部类的成员,也可以访问方法内的局部变量

    public class Demo_局部内部类 {
        public static void main(String[] args) {
            breath();
        }
    
        public static void breath(){
            // 1. count作为局部变量不能单独获取到, 只能跟着breath方法运行使用
            int count = 10;
            // 2. 局部内部类, 与局部变量类似,只能在方法中定义使用
            class Fei{
                String color = "black";
                public void show(){
                    System.out.println("每天吸" + count + "跟烟,总有一天肺就会变成" + color);
                }
            }
            // 3. 局部变量,直接在方法中创建对象使用
            Fei f = new Fei();
            System.out.println(f.color);
            f.show();
        }
    }

    三. final关键字

    1、final是一个关键字 含义:最终的,最后的,表示不能再改变的。

    2、final关键字:可以修饰类、方法、变量

    3、修饰类:

            (1) 表示一个最终类,表示不能有子类,【不能被其他类继承】

            (2) 一旦一个类型不能被继承,那么其中所有的方法都不能被重写

            (3) 不影响当前类的方法被调用

    4、修饰方法:

           表示一个最终方法,【该方法不能被重写】

    5、修饰变量:

           (1) 表示一个最终变量,该【变量变成了常量】,就只能赋值一次

           (2) 当前项目中,常用的常量一般都定义在一个类的成员位置,甚至专门定义一个常量类,常量命名规范: 所有单词全大写, 多个单词之间使用_进行分隔了,举例: SCHOOL_NAME  PI

           (3) 定义常量的好处:见名知意,容易理解;可维护性高

     

    final修饰类代码

    // final修饰的类没有子类
    public final class FinalClass {
        int i = 10;
        static int w = 20;
        public void fun(){
            System.out.println("我是final类中的fun方法");
        }
    }
    /*public class FinalClassSub extends FinalClass{ // 报错
    }*/

    final修饰方法:

    public class FinalMethod {
        public final void eat(){
            System.out.println("我是final修饰的吃饭功能, 不能被继承,但是可以直接使用");
        }
    }
    public class FinalMethodSub extends FinalMethod{
        // 子类继承到了父类中的eat方法,但是因为这个方法是final修饰的,只能使用不能重写
        /*public void eat(){
            System.out.println("我是final修饰的吃饭功能, 不能被继承,但是可以直接使用");
        }*/
    }

    final修饰变量:

    public class FinalVariable {
        // 5. final修饰成员变量: 最好直接赋值(扩展: final修饰成员变量, 必须在创建对象完成之前进行手动赋值)
        final String name = "张三";// 最推荐
        final String sex;
    
        public FinalVariable(){
            sex = "男";
        }
        int w = 99;
        // 1. final修饰的变量值不能发生改变, final固定的数据第一次手动赋值
        // 2. final修饰的变量称为常量: 所有单词全大写, 多个单词之间_分隔
        public static void main(String[] args) {
            final int I = 10;
            // 3. final修饰基本数据类型,其数值不能发生修改
            // I = 19;
            // 4. final修饰引用数据类型,那么表示这个引用地址值不能发生改变
            final FinalVariable fv = new FinalVariable();
            // fv = new FinalVariable();
            fv.w = 888;
        }
    }

    final代码测试类:

    public class TestFinal {
        public static void main(String[] args) {
            // 1. 测试final修饰的类可以正常使用
            FinalClass fc = new FinalClass();
            System.out.println(fc.i);
            System.out.println(FinalClass.w);
            fc.fun();
    
            // 2. 测试final修饰的方法可以被子类继承, 也可以正常使用
            FinalMethodSub fms = new FinalMethodSub();
            fms.eat();
    
            FinalMethod fm = new FinalMethod();
            fm.eat();
        }
    }

    四. 包

    1. 包的概述: 用来统一分类管理源代码资源的特殊文件夹;这个文件夹会参与编译。

    比如:

          com.ujiuye.demo 下的 Person类进行编译的时候类所在的包参与编译,编译后

            字节码文件名:com.ujiuye.demo.Person

            字节码文件中类名:com.ujiuye.demo.Person【全限定类名】  

     

    2. 作用:

      (1) 统一管理代码资源

      (2) 保证代码编译后类名唯一

      (3) 保证代码运行的过程直接进入包找到对应的类

     

    3. 命名规则:

      (1) 使用公司域名的反写【保证每一个包路径唯一】

      (2) 全部小写

      (3) 包名和包名之间使用.隔开

     

    4. 包的声明:

       使用关键字 package + 包路径【IDE生成类的时候自动声明】

     

    5. 导包:

      同包下:不需要导包

      不同包:需要导包【jdk的lang包除外】

      使用 import + 包路径

     

    6. 注意:

      (1) 没有导包格式之前:使用类的时候不导包的直接使用全限定类名进行使用

                     比如:java.util.Scanner sc = new java.util.Scanner(System.in);

      (2) 使用全限定类名使用类的时候,有点麻烦进行了简化:

                     使用import关键字进行提取导包进行导包

      (3) 作用

        可以把同名字的类使用包做一个详细的划分

    import com.ujiuye.homework.Phone;
    
    public class Test {
        // com.ujiuye.innerclass.Test
        // com.ujiuye.block.Test
        Phone p = new Phone();
    
        // java.lang包下的所有类型可以直接使用, 不需要导包
        String str = "abc";
    }

    五. 权限修饰符

    1. 概述: 用来限定资源的使用范围的修饰词汇,就叫做权限(使用)修饰符,不同的符号有不同的限定范围

    2. 分类: 从小到大权限罗列

      private :私有的     限定范围:本类中使用

    默认的 :啥也不写    限定范围:本类和本包中使用

    protected :受保护的  限定范围:本类和本包中使用,不同包下的子类内部可以使用

    public :公共的      限定范围:没有范围

     

    3. 注意:

    1) protected 只修饰方法和变量, 不能修饰类; 保护的是外包子类的内部

    2) 总结: 修饰成员变量,为了满足封装特点,使用private修饰;

             修饰类,和普通方法功能, 通常使用public修饰

     

     

    // DefaultClass是默认权限修饰的类: 使用范围本包中使用
    class DefaultClass {
        // 默认权限成员变量
        String name = "李四";
        // 默认权限方法
        void fun(){
            System.out.println("我是默认的方法fun");
        }
    }
    public class ProtectedClass {
        protected double height = 175;
        protected void sleep(){
            System.out.println("我是受保护的休眠方法" + height);
        }
    }
    public class PublicClass {
        public String sex = "女";
    
        public void happy(){
            System.out.println("happy" + sex);
        }
    }
    public class TestQuanXian {
        public static void main(String[] args) {
            // 1. 默认修饰的类型, 可以在本包中使用
            DefaultClass sc = new DefaultClass();
            sc.fun();
            System.out.println(sc.name);
    
            // 2. 受保护权限可以在本包中使用
            ProtectedClass pc = new ProtectedClass();
            System.out.println(pc.height);
            pc.sleep();
        }
    }
    import com.ujiuye.quanxian.ProtectedClass;
    
    public class ProtectedClassSub extends ProtectedClass {
        // ProtectedClassSub子类继承到了父类中的两个受保护成员
        // double height = 175;  sleep方法
        // 这两个受保护在子类中相当于private使用
        public void useProtected(){
            System.out.println(height);
            sleep();
        }
    }
    //import com.ujiuye.quanxian.DefaultClass;
    
    import com.ujiuye.quanxian.ProtectedClass;
    import com.ujiuye.quanxian.PublicClass;
    
    public class Test {
        public static void main(String[] args) {
            // 1. 测试默认权限不能在其他包中使用
           // DefaultClass sc = new DefaultClass();
           // System.out.println(sc.name);
    
            // 2. 测试受保护权限在外包子类之外不能使用
            ProtectedClass pc = new ProtectedClass();
            // pc.sleep();
    
            ProtectedClassSub pcs = new ProtectedClassSub();
            // pcs.sleep();
            // System.out.println(pcs.height);
    
            // 3. 测试公共修饰的类型可以任意使用, 没有限制
            PublicClass pub = new PublicClass();
            System.out.println(pub.sex);
            pub.happy();
        }
    }

    修饰符关键字:

    private 私有: 封装特性

    static 静态: 属于类,跟着类存储在方法区中静态区域中, 就只有一份, 可以被所有对象共享使用

    final 最后的, 不可改变的: 修饰类, 修改方法, 修饰变量(常量)

    默认权限在类中不写出来, 写了反而代码报错

    protected

    public

     

    六. 匿名内部类

    1、没有名字的内部类

    2、匿名内部类的使用前提:

            匿名类:继承一个类

           匿名类:实现一个接口

    1、格式:

           new 父类类名或者接口名() {

                父类方法的重写或者是接口内容的实现

    }

    2、本质:

      (1) 创建了一个类的子类对象、接口的实现类对象

      (2) 更强调关系的一种写法

    5、内部类的名称总结:

           (1) 如果是有名字的内部类,类名【外部类名$内部类名】

           (2) 如果是没有名字的内部类,通过匿名内部类的顺序描述类名,第一个匿名内部类的名称【外部类名$1】,第二个匿名内部类类名【外部类名$2】

    public class 匿名内部类 {
        public static void main(String[] args) {
            // 1. 匿名内部类可以作为一个类的子类对象存在
            /*
                 new 类名(){// 大括号就表示类的子类实现过程
                 };
             */
            new Animal(){
                @Override
                public void eat(){
                    System.out.println("不同动物吃不同的实物");
                }
            }.eat();
        }
    }

    代码块总结

    1、局部代码块:
    - 作用
    - 限定 定义在局部代码块的中变量的作用范围
    - 优势
    - 不仅仅是范围的限定,也是变量在内存中储存时间的限定,(使用完成后,局部代码块外无法再调用 内存回收)

    2、构造代码块:在构造方法之前调用,通常用于提取无参构造跟有参构造公共代码

    3、静态代码块
    1. 可以给类型中的静态成员变量进行赋值
    2. 静态代码块运行时机: 因为静态都属于类, 因此在当前类进入内存时候(进入方法区),JVM虚拟机主动调用
    静态代码块一次
    3. 静态代码块使用场景: 如果有代码只需要执行一次, 并且是在所有其他代码运行之前就执行, 那么这些逻辑
    可以设计在静态代码块中
    举例: 数据库,持久性的存储数据; 需要在交易开始之前, 保证数据库连接成功的
    (登录数据库,读取数据库登录时用户名和密码)
    连接数据库的过程就可以设计在静态代码块中

    内部类总结


    1、普通成员内部类
    - 定义位置
    - 类中,方法外,跟成员变量同级的位置

    - 访问方式
    1) 内部类可以直接使用外部类包括的私有属性和方法
    2) 外部类访问普通内部类必须通过对象 (类中)
    // 1)
    Wrapper war = new Wrapper();
    Wrapper.Inner inn = war.new Inner();
    // 2)
    Wrapper.Inner inn2 = new Wrapper().new Inner();


    2、私有的成员内部类
    - 定义位置 跟普通成员内部类的区别是 前面加上private
    - 访问方式:
    1) 在外部类以外,不能直接访问外部类中的私有成员内部类
    2) 可以在外部类中,定义一个访问私有成员内部类的公有方法,
    让外界可以调用公有方法,间接的访问外部类中的私有成员内部类。


    3、静态的成员内部类
    - 定义位置,也是一个成员内部类,在成员内部类前面加上一个static关键字
    - 访问方式:
    1) 是外部类的静态成员,所以可以直接类名.静态内部类 使用
    2) 如果需要调用 静态类的成员,需要观察静态内部类的成员是否是静态的,
    如果是静态的可以直接调用,非静态则需要创建对象调用。

    static class StaticInner {
    public String name3 = "静态成员内部类-公有局部变量";
    private String name33 = "静态成员内部类-私有局部变量";
    static String name333 = "静态成员内部类-静态局部变量";

    public String getName33() {
    return name33;
    }

    public void staticMethod() { // 静态的成员内部类方法
    System.out.println("静态的成员内部类方法");
    }
    }

    Wrapper.StaticInner inn3 = new Wrapper.StaticInner();
    System.out.println(Wrapper.StaticInner.name333); // 静态内部类静态属性
    System.out.println(inn3.getName33()); // 静态内部类私有属性
    System.out.println(inn3.name3); // 静态内部类公有属性
    inn3.staticMethod(); // 静态内部公有有方法

    4、局部内部类
    - 定义位置: 局部内部类是定义在方法中的类
    - 访问方式:
    1) 局部内部类,外界是无法直接使用,需要在方法内部创建对象并使用
    2) 该类可以直接访问外部类的成员,也可以访问方法内的局部变量

    public void localFunc() {
    String name4 = "局部变量";

    class LocalInner{
    private String name5 = "局部内部类";

    public String getName4() {
    return name4;
    }
    }
    // 局部内部类无法在 外部使用,只能在方法中创建对象使用,可以使用方法的局部变量
    LocalInner l = new LocalInner();
    l.getName4();
    }


    public class Demo_局部内部类 {
    public static void main(String[] args) {
    breath();
    }

    public static void breath(){
    // 1. count作为局部变量不能单独获取到, 只能跟着breath方法运行使用
    int count = 10;
    // 2. 局部内部类, 与局部变量类似,只能在方法中定义使用
    class Fei{
    String color = "black";
    public void show(){
    System.out.println("每天吸" + count + "跟烟,总有一天肺就会变成" + color);
    }
    }
    // 3. 局部变量,直接在方法中创建对象使用
    Fei f = new Fei();
    System.out.println(f.color);
    f.show();
    }
    }

  • 相关阅读:
    2014年7月 记事
    从客户端中检测到有潜在危险的Request.Form值 的解决方法
    jquery parent() parents() closest()区别
    不包含适合于入口点的静态"Main"方法
    JQuery移除事件
    jQ的toggle()方法示例
    codeforces hello2018 D Too Easy Problems
    HDU-6084 寻找母串
    51Nod 1109 01组成N的倍数
    可重排列
  • 原文地址:https://www.cnblogs.com/lw1095950124/p/15977669.html
Copyright © 2020-2023  润新知