当前位置: 移动技术网 > IT编程>开发语言>Java > JavaSE学习笔记 - 面向对象基础

JavaSE学习笔记 - 面向对象基础

2020年07月31日  | 移动技术网IT编程  | 我要评论
属性面向过程的编程思想:解决问题的时候按照一定的过程(流程),以过程为本 – 不好复用,增加了很多冗余面向对象的编程思想:解决问题的时候按照现实生活中的规律来考虑问题,考虑在这个问题的过程中,有几个实体参与进来,实体是动作的支配者,没有实体动作就发生不了类和对象类-人类抽象笼统的概念,描述一类事物,肯定是具有相同的特征行为对象-具体的人人类中的一个具体的人在现实生活中,对象是先有的总结出来的概念是后产生的在计算机中利用面向对象的思想来做事需要先自己定义一个类(类型)想要做事情需

面向对象

  • 面向对象特点:封装性、继承性、多态性、(抽象性)
  • 面向对象:不关心具体的步骤,具体的步骤已经由某一个对象完成,考虑哪一个对象完成了这个事情,找到这个对象来做某一件事情。
  • 面向过程:需要考虑具体的过程,要自己考虑每一步的实现过程,考虑怎么去做。
  • 类和对象:创建类,设计类的属性;创建类的对象;通过 “对象.属性”,"对象.方法"调用对象的结构,功能。
  • 万物皆对象:在 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;
    }

}

本文地址:https://blog.csdn.net/qq_42217376/article/details/107523969

如您对本文有疑问或者有任何想说的,请 点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网