其他分享
首页 > 其他分享> > 20220727 第五小组 罗大禹 学习笔记

20220727 第五小组 罗大禹 学习笔记

作者:互联网

20220727 第五小组 罗大禹 学习笔记

Java 静态、内部类及代码块

学习重点

1.类的内部结构
2.单例模式

学习心得

今天老师讲的内容较为零散,需要自己好好整理下知识点。

学习内容

Java 静态、内部类及代码块

类的内部结构:

属性、方法、构造器、代码块、内部类

static静态(理解)

​ 可修饰:属性(被修饰后称为类属性),方法(被修饰后被称为类方法),代码块

注意:

用static修饰的结构,不属于任何一个对象

this和super

无论是this还是super,都不可以在静态结构中使用。

静态结构是属于类的,静态结构是优先于对象就存在的。

this和super,必须有对象才能出现。必须得有实例。

static内存解析:

​ 1、静态的变量或者静态方法存在于方法区的。静态的结构不会被垃圾回收。

​ 2、不属于某一个实例对象,只存在于方法区。调用静态结构,直接用类名.的方式。

实例方法和静态方法互相调用:
  1. 静态方法中不可以直接调用实例方法!!

​ 如果想用,必须对象.方法名 对象.属性名

  1. 实例方法中可以直接调用静态方法!!

    可以直接 ①类名.方法 ② 类名.属性名 进行调用

加载
  1. 静态的结构的加载,随着类的加载而加载!!!
  2. 非静态的结构,随着对象的创建而加载!!!
平时用的静态方法

Arrays.toString();

Arrays.sort();

Integer.parseInt();

String.valueOf();

举例说明:
public class Ch03 {

    static String name = "啦啦啦";
    int age = 20;
    String str = "哈哈";

    public Ch03(){
        show();
    }
	//实例方法
    public void fun(){
        show();
    }

    // 静态方法
    public static void show(){        
        System.out.println("静态方法...");
        new Ch03().fun();
    }

    public static void main(String[] args) {
        System.out.println(Ch03.name);
        //直接调用静态方法
        Ch03.show();
        Ch03 ch03 = new Ch03();
        System.out.println(ch03.name);
        //通过对象调用静态方法
        ch03.show();
    }
}
注意:

静态方法无论在哪里都是类名.方法名调用,同一个类的静态方法之间可以省略类名。

用对象.方法或对象.属性是可以调用的,但严格来说,用对象来调用静态的方法、属性是错误的,尽量不要这么调用,建议直接 类名.静态属性(方法)

静态方法没有重写的概念
代码块(不是方法):(理解)

​ 代码块又称为初始化块,属于类的一个成员,它是将逻辑语句封装在方法体中。

​ 通过{}包裹。代码块没有方法名,没有参数,没有返回值,只有方法体。

​ 他是不需要通过对象或类进行显示的调用,他会在类加载或者创建对象时主动的《隐式》调用。

​ 可用于给静态常量初始化,创建静态常量不初始化,在代码块中初始化是可以的

1、静态代码块

​ 一个类被加载时会被调用一次,做一些初始化的工作(只走一次)

​ 可以写多个静态块,但一般只写一个

2、实例代码块

​ 每次创建实例(创建对象)时,会被调用一次,用的较少(每次创建对象都走)

​ 可以写多个,但一般只写一个

举例说明
public class Ch01 {
	static final String STR;
    static {
        // 静态代码块
        System.out.println("静态代码块...");
        STR = "10";
    }

    {
        // 实例代码块
        System.out.println("实例代码块...");
    }

    public static void main(String[] args) {        
        Ch01 ch01 = new Ch01();
        Ch01 ch02 = new Ch01();
        /*会输出: 静态代码块
       		      实例代码块
                  实例代码块
       */
        //因为静态代码块只在类被加载时被调用一次(无论再怎么创建对象都只走一次)
        //实例代码块会随着对象的一次创建而被调用一次

    }
}
面试题
//父类
public class Father {

    public Father() {
        System.out.println("父类的构造器...");
    }
    {
        System.out.println("父类的实例块...");
    }
    static {
        System.out.println("父类的静态块...");
    }

    public static void main(String[] args) {
        Father father = new Father();
    }
}

//子类
public class Ch02 extends Father {

    public Ch02() {
        System.out.println("子类的构造器...");
    }
    {
        System.out.println("子类的实例块...");
    }
    static {
        System.out.println("子类的静态块...");
    }

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

问:输出的顺序是?

​ 当没有继承关系,就一个类时,静态块-->实例块-->构造器

​ 当有继承关系时,父类的静态块-->子类的静态块-->父类的实例块-->父类的构造器-->子类的实例块-->子类的构造器

父类优于子类,静态优于非静态

内部类:(理解)

在一个类内部进行其他类结构的嵌套操作。

  1. 实例内部类

    实例内部类中除了静态常量之外,其他的静态不能存在

  2. 静态内部类

举例说明:

public class Ch01 {
    // 实例内部类
    // 不能有静态
    public class Inner {
        public static int x;
        {
            System.out.println("实例内部类被加载...");
        }
        public void show(){

        }
        public Inner(){

        }
        class Innerinner{

        }
        private String name;

    }
    // 静态内部类
    public static class InnerStatic {
        static {
            System.out.println("静态内部类被加载...");
        }
        public void show(){

        }

        public static void main(String[] args) {

        }
    }

    public static void main(String[] args) {
        // 这就是实例内部类的对象
        Inner inner = new Ch01().new Inner();
        // 静态内部类的对象
        InnerStatic innerStatic = new Ch01.InnerStatic();
    }
}

外部类(理解)

若外部类想用public声明,则类名必须和.java的文件名相同。

外部类就是两个类,生成的.class文件是两个独立的.class。

开发中,尽量不要写外部类。

举例说明:
public class Ch05 {

    int i = 10;

    public static void main(String[] args) {

    }
}

//外部类
class Outer {
    public static void main(String[] args) {

    }
}

设计模式

设计模式是人们为软件开发中抽象出可重复利用的解决方案。
软件开发工程师之间沟通的“行话”。

面向对象的设计原则(了解)
  1. 开闭原则(Open Close Principle)
    对扩展开放,对修改关闭。(继承,实现接口)

    ​ 我们可以通过“抽象约束,封装变化”来实现开闭原则。

    ​ 通过接口或者抽象类为软件定义一个相对稳定的抽象层。

    ​ 将相同的可变因素封装在相同的具体实现类中。派生一个实体类就可以了。

  2. 里氏代换原则

    ​ 子类继承父类时,除了添加新的方法完成新增的功能外,尽量不要重写父类的方法

  3. 依赖倒转原则

    ​ 要面向接口编程,不要面向实现编程。

    ​ a. 每个类尽量提供接口或抽象类,或者两者兼备

    ​ b. 变量的类型声明尽量是接口或者是抽象类

    ​ c. 任何类都不应该从具体类派生

    ​ d. 使用继承时,要遵循里氏代换原则。

  4. 接口隔离原则
    使用多个隔离的接口。

  5. 迪米特法则

  6. 合成复用原则

  7. 单一原则:一个类只做一件事

单例模式(理解)

一个类只有一个实例。

思路:

  1. 别人不能new,构造器私有化,不能在类的外部通过new去实例化。
  2. 在该类内部产生一个唯一的实例对象,把它封装成static类型。
  3. 定义一个静态方法返回这个唯一的对象。
饿汉式单例模式

​ 不管以后会不会使用到该实例化对象,先创建了再说,很着急的样子。

​ 实现的办法就是直接new实例化。

public class Ch03 {

    private static final Ch03 ch03 = new Ch03();

    private Ch03(){}

    public static Ch03 getInstance(){
        return ch03;
    }
}
懒汉式(延迟加载)

​ 什么时候调用getInstance方法,什么时候new

​ 这种懒汉式在多线程环境中完全错误的,根本不能保证单例的状态,可能会出现线程问题。

​ 需要《加锁》

举例说明
public class Ch04 {
    // 将自身实例化对象设置为一个属性,现在是没有赋值的
    private static Ch04 ch04;
    
    // 构造器私有化
    private Ch04(){
        
    }
    public static Ch04 getInstance()  {
        if(ch04 == null){
            ch04 = new Ch04();
        }
        return ch04;
    }
}
内部类实现单例

​也是懒汉式的一种,这种懒汉式没有线程的问题。

结合了饿汉式和懒汉式的优点:

只要不调用getInstance方法,就不会使用内部类

内部类一旦被使用一次只会被初始化一次,以后一直用的时INSTANCE静态常量了。

public class Ch05 {
    // 私有化构造器
    private Ch05(){

    }
    
    public static Ch05 getInstance() {
        return SingletonHolder.INSTANCE;
    }

    private static class SingletonHolder {
        private static final Ch05 INSTANCE = new Ch05();
    }
}

箭头函数:JDK8的新特性(理解)

​ 函数式接口:如果一个接口只有一个抽象方法,这个接口就称为函数式接口。可以用注解@FunctionalInterface标识。

  1. 有参数,有返回值。
    (i,j) -> {
    return i + j;
    }
    如果方法体只是一句返回值(i,j) -> i+j
  2. 有参数,无返回值
    (i,j) -> {
    // 方法体
    }
    如果方法体只有一句话(i,j) -> 方法体的一句话
  3. 无参数
    ()->{
    方法体
    }
//接口
@FunctionalInterface
public interface Inter01 {
	//抽象方法
    String show();
    //默认方法
    default void fun(){

    }
}

//类
public class Ch06 {

    public static void test(Inter01 inter01) {
//        System.out.println(inter01.show());
        inter01.show();
    }

    public static void main(String[] args) {
        
       	//老方法,使用匿名实现类来完成重写
        test(new Inter01() {
            @Override
            public String show(int i,int j) {
                return i + "," + j + "匿名实现类重写的show方法...";
            }
        });
        
        //箭头函数
        /*
            这个结构可以分为三部分
            第一部分,小括号包裹形参,类型不要
            第二部分,->
            第三部分,->方法体
            当重写的方法体只有一句话时,可以精简到这种
            () ->System.out.println("重写的show方法...")
            当重写的方法只是有一句返回值时,可以精简到这种 
            () -> "你好"
         */
        //test((1,2) -> {方法体});
        test(() -> "你好");
    }
}

标签:20220727,笔记,class,静态,实例,static,大禹,new,public
来源: https://www.cnblogs.com/ldydj/p/16526742.html