• JavaSE学习笔记


    面向对象

    • 面向对象特点:封装性、继承性、多态性、(抽象性)
    • 面向对象:不关心具体的步骤,具体的步骤已经由某一个对象完成,考虑哪一个对象完成了这个事情,找到这个对象来做某一件事情。
    • 面向过程:需要考虑具体的过程,要自己考虑每一步的实现过程,考虑怎么去做。
    • 类和对象:创建类,设计类的属性;创建类的对象;通过 "对象.属性","对象.方法"调用对象的结构,功能。
    • 万物皆对象:在 Java 语言范畴中,我们将功能、结构等封装到类中,通过类的实例化,来调用具体的功能结构。(Scanner,String,File,URL),涉及到Java语言与前端 HTML、后端数据库交互的时候,前后端的结构在Java层面交互的时候都体现为类和对象。

    JVM内存结构

    • 编译完源程序以后,生成字节码文件;使用 JVM 中的类加载器和解释器对生成的字节码文件进行解释运行。需要将字节码文件对应的类加载到内存中,涉及到内存解析。内存解析是在运行的时候进行的。

    方法的使用

    • 方法重载(OverLoad):对于功能类似的方法来说,参数列表不一样,可以使用相同的方法名,多个方法的名称一样,但是参数列表不同,使用一个方法名称,就可以实现相似的多个功能。
    • 可变个数形参的格式:数据类型...变量名,可变参数必须声明在形参的末尾。
    • 方法递归:方法自身调用自身,使用递归的时候必须添加结束条件,如果没有结束条件将会反生栈溢出。 StackOverflowError,当没有递归出口的时候,方法就会被一直压栈,直到栈内存被全部占满。

    递归调用内存图
    在这里插入图片描述

    方法参数的值传递

    • 如果变量是基本数据类型,赋值的时候就是变量保存的数据值。如果变量是引用数据类型,赋值的时候就是变量保存的地址值。
    • 如果变量作为参数进行值传递,此时在方法中这个值是形参。如果参数是基本数据类型,此时实参给形参的是实参的真实数据值。如果参数是引用数据类型,此时实现给形参的是实参的存储数据的地址值。

    代码块

    • 作用:跟普通方法一样,完成某一个功能的
    • 写法:可以认为程序块是一个 没有修饰符 没有参数 没有返回值 没有名字的特殊方法
    • 用法:块也需要调用才能执行 我们自己调用不到(没有名字) 每一次我们调用构造方法之前 系统会帮我们自动的调用一次程序块 让他执行一遍
    • 特点:没有什么重载的概念(名字,参数都没有,但是可以在类中定义 多个程序块)
    • 块可以在里面写一些程序,在创建对象之前执行
    //在运行的时候自动执行
    public class Main {
        public static void main(String[] args) {
            {
                System.out.println(5);
            }
        }
    }
    

    this关键字

    • 构造方法中,属性与变量名重名的时候,this 表示当前对象,是一个关键字(指代词)代替的是某一个对象(当前调用属性或者方法时的那个对象)
    • 调用属性或者方法这一行代码可以放置在类中的任何成员位置 上下顺序随意
    • this可以调用构造方法:构造方法,一般方法,有顺序,认为构造方法早于一般方法,一般方法内不能调用构造方法,构造方法可以重载,在有参构造方法中调用无参构造方法 this() 省略了构造方法的名字,必须与类名一致,方法之间来回的调用是不可以的。
    public class Person {
        int no;
        String name;
        public Person() {
            System.out.println("无参构造方法执行了...");
        }
    
        public Person(int no, String name) {
            this();
            this.no = no;
            this.name = name;
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            Person person = new Person(2017, "张三");
            System.out.println(person);
        }
    }
    

    static关键字

    static在属性上:类属性,静态属性

    • 类属性的访问可以通过类名.类属性,还可以通过对象.类属性访问。类属性的当前的字节码文件加载进 JVM 的时候,类属性就会被初始化,JVM 执行完毕字节码文件才销毁。
    • 类属性可以被每一个对象共享,类方法初始化很早,JVM 加载这个类的时候这个方法就初始化了,对象方法也是很早就进入 JVM,但是不一定被启用了,只有先创建了对象才能调用方法。
    • 静态变量对于所有的对象来说都共享一个静态变量,而非类中静态变量对于每一个对象都有单独的一份。

    static在方法上:类方法(作为工具类使用)

    • 类方法不能访问对象的属性,类方法加载的比较早,也不能调用对象方法。类方法只能访问类属性和类方法。
    • 对象方法内可以访问类方法

    静态代码块

    • 主要用于初始化资源;静态代码块在 main 之前执行,因为静态代码块在类加载的时候就执行了;不能访问对象属性和对象方法,静态方法和静态代码块没有顺序;一个类中可以写多个静态代码块,这些代码块遵循自上而下的顺序依次执行。(如果想要在类进行加载的时候就执行某些代码,那么可以使用静态代码块。)

    单例模式 *

    类加载机制、字节码知识、JVM 指令重排、Java 序列化机制
    一个类只能创建一个实例,设计一个类只能有一个对象,不能创建第二个对象。(线程池,数据库连接池)
    实现步骤

    • 私有化构造器
    • 定义一个类方法用于获得单例的对象,返回值是这个类的类型
    • 在类中提供一个私有的 Singleton 类型的类属性(静态属性)
    • 实现 getInstance 这个方法

    实现方式

    • 懒汉模式:使用的时候再进行初始化,延迟加载。
    public class Main {
        public static void main(String[] args) {
            Singleton singleton = Singleton.getInstance();
            Singleton singleton1 = Singleton.getInstance();
            System.out.println(singleton);//cn.edu.zut.Singleton@1b6d3586
            System.out.println(singleton1);//cn.edu.zut.Singleton@1b6d3586
        }
    }
    
    //懒汉模式
    class Singleton {
        //只能有一个实例
        private static Singleton singleton;
        //私有化构造方法
        private Singleton() {
    
        }
        public static Singleton getInstance() {
            if (singleton == null) {
                //收到编译器的影响,可能会先执行3,在执行2,指令集进行重新排序,加上volatile(多线程编程)
                //首先在堆空间分配一个空间,然后在栈空间赋值一个引用,分配空间的时候会返回一个该空间的内存引用
                //初始化空间
                //把内存引用赋值给singleton
                singleton = new Singleton();
            }
            return singleton;
        }
    }
    
    • 饿汉模式:在类加载的时候就完成了实例的初始化。类加载:加载对应的二进制文件,在方法区,创建对应的数据结构;连接,1.验证,2.准备(给变量初始值),3.解析;初始化:给静态属性赋值。(通过类加载机制,来保证线程安全。)
    public class Main {
        public static void main(String[] args) {
            Singleton singleton = Singleton.getInstance();
            Singleton singleton1 = Singleton.getInstance();
            System.out.println(singleton);//cn.edu.zut.Singleton@1b6d3586
            System.out.println(singleton1);//cn.edu.zut.Singleton@1b6d3586
        }
    }
    
    //饿汉模式
    class Singleton {
        //只能有一个实例
        private static Singleton singleton = new Singleton();
        //私有化构造方法
        private Singleton() {
    
        }
        public static Singleton getInstance() {
            return singleton;
        }
    }
    
    • 静态内部类:延迟加载
    public class Main {
        public static void main(String[] args) {
            Singleton singleton = Singleton.getInstance();
            Singleton singleton1 = Singleton.getInstance();
            System.out.println(singleton);//cn.edu.zut.Singleton@1b6d3586
            System.out.println(singleton1);//cn.edu.zut.Singleton@1b6d3586
        }
    }
    
    //静态内部类:延迟加载
    class Singleton {
    
        static class InnerClass {
            private static Singleton singleton = new Singleton();
        }
    
        private Singleton() {
    
        }
        public static Singleton getInstance() {
            //在调用这个的时候,InnerClass会进行加载
            return InnerClass.singleton;
        }
    }
    
    • 反射攻击:通过反射机制来创建不同的实例
    public class Main {
        public static void main(String[] args) throws Exception {
            Constructor<Singleton> constructor
                    = Singleton.class.getDeclaredConstructor();
            constructor.setAccessible(true);
            Singleton singleton = constructor.newInstance();
    
            Singleton singleton1 = Singleton.getInstance();
            System.out.println(singleton);//cn.edu.zut.Singleton@1b6d3586
            System.out.println(singleton1);//cn.edu.zut.Singleton@4554617c
        }
    }
    
    class Singleton {
    
        static class InnerClass {
            private static Singleton singleton = new Singleton();
        }
    
        private Singleton() {
    
        }
        public static Singleton getInstance() {
            //在调用这个的时候,InnerClass会进行加载
            return InnerClass.singleton;
        }
    }
    
    • 枚举类型:使用反射机制的时候会直接抛出异常,枚举类型不支持反射创建。
    public class Main {
        public static void main(String[] args) throws Exception {
            Enum singleton = Enum.SINGLETON;
            Enum singleton1 = Enum.SINGLETON;
            System.out.println(singleton);//SINGLETON
            System.out.println(singleton1);//SINGLETON
            System.out.println(singleton.hashCode());//460141958
            System.out.println(singleton1.hashCode());//460141958
    
            Constructor<Enum> constructor = Enum.class.getDeclaredConstructor(String.class, int.class);
            constructor.setAccessible(true);
            Enum singleton2 = constructor.newInstance("SINGLETON", 0);
            //java.lang.IllegalArgumentException: Cannot reflectively create enum objects
            //不能对枚举类型进行实例化
            System.out.println(singleton2);
    
        }
    }
    
    
    enum Enum {
        SINGLETON;
    //     0: new           #4                  // class cn/edu/zut/Enum 分配空间
    //     3: dup
    //     4: ldc           #7                  // String SINGLETON   加载实例
    //     6 : iconst_0
    //     7: invokespecial #8                  // Method "<init>":(Ljava/lang/String;I)V 调用构造方法
    //     10: putstatic     #9                  // Field SINGLETON:Lcn/edu/zut/Enum;  对静态属性进行赋值
    //     13: iconst_1
    //     14: anewarray     #4                  // class cn/edu/zut/Enum
    //     17: dup
    //     18: iconst_0
    //     19: getstatic     #9                  // Field SINGLETON:Lcn/edu/zut/Enum;
    //     22: aastore
    //     23: putstatic     #1                  // Field $VALUES:[Lcn/edu/zut/Enum;
    //     26: return
    
    }
    
    • 序列化
    public class Main {
        public static void main(String[] args) throws IOException, ClassNotFoundException {
            Singleton singleton = Singleton.getInstance();
            //序列化
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("singleton"));
            oos.writeObject(singleton);
            oos.close();
            //反序列化
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("singleton"));
            Object obj = ois.readObject();
            Singleton singleton1 = (Singleton) obj;
    //        System.out.println(singleton1);//cn.edu.zut.Singleton@378bf509
    //        System.out.println(singleton);//cn.edu.zut.Singleton@7f31245a
    
            //添加Object readResolve() throws ObjectStreamException,接口中的替代方法,防止反序列化攻击
            //枚举类型也可以防止反序列化攻击
            System.out.println(singleton1);//cn.edu.zut.Singleton@7f31245a
            System.out.println(singleton);//cn.edu.zut.Singleton@7f31245a
        }
    }
    
    class Singleton implements Serializable {
        private static final long serialVersionUID = -8122532461435652822L;
        private static Singleton singleton = new Singleton();
        private Singleton() {
    
        }
        public static Singleton getInstance() {
            return singleton;
        }
    
        Object readResolve() throws ObjectStreamException {
            return singleton;
        }
    
    }
    
  • 相关阅读:
    显示非模式窗口和模式窗口
    delphi 版本号
    数字证书和签名
    DLL知道自己的位置
    拖动处理
    驱动配置相关
    python sturct模块操作C数据
    Lambda学习笔记
    【转】update select
    [转]视频格式分类
  • 原文地址:https://www.cnblogs.com/zut-syp/p/13570696.html
Copyright © 2020-2023  润新知