李剑辰 0727

一.代码块

二.实列方法与静态方法

三.内部类

四.设计模式

五.单例模式

一.代码块

1.普通代块:类中方法的方法体,使用较少

public class Main{
	public static void main(String[] args) {
		{ 
		  ...普通代码块
		 }
	}
}

2.实例代码块(构造代码块):定义在类中的代码块,不加修饰符,一般用于成员变量初始化

public class Person {
    String name;
    String sex;
    int age;

    {
        this.name = "花花";
        this.sex = "女";
        this.age = 3;
        System.out.println("我是实例代码块");
    }

    public static void main(String[] args) {
        Person person1 = new Person();
        Person person2 = new Person();
        Person person3 = new Person();
    }
}

输出为:
由此可知:实例代码块在每次创建对象时都会被调用

3.静态代码块:由static{...}包裹起来的代码块,优先与构造代码块执行,一般用来初始化静态成员变量,层级为类级

public class Person {
    String name;
    String sex;
    int age;

    static {
        System.out.println("我是静态代码块");
    }

    public static void main(String[] args) {
        Person person1 = new Person();
        Person person2 = new Person();
        Person person3 = new Person();
    }
}

输出为:

由此可知,无论创建多少给对象,静态代码块只会执行一次

二.实列方法与静态方法

1.实例方法:只能实例化对象来调用,实例名.方法名。在本类中可以任意访问其它成员,没有限制
2.静态方法:可以通过类名.方法名来调用,在本类中只能访问静态成员(静态成员变量和静态方法)

public class Cat {
    public static void main(String[] args) {

        // 使用对象调用 不推荐!
        new Cat().isStatic();
        // 调用静态方法无需创建对象,因为在java虚拟机加载类的时候就会把该类的静态方法直接加载到内存中,给静态方法分配一个内存空间
        Cat.isStatic();

        // 实例方法只能通过创建对象来调用
        Cat cat = new Cat();
        cat.notStatic();

    }
    public static void isStatic(){
        // 由于静态方法不能通过对象进行调用,故静态方法里面不能调用非静态变量或非静态变量成员
        System.out.println("静态方法");
    }

    public void notStatic(){
        System.out.println("实例方法");
    }
}

运行结果为:

  • 总结:static的主要作用在于创建独立于具体对象的域变量或者方法,所以静态方法和变量都是在类装载的时候装载的,这时候还没有产生对象,它们是属于类本身的,这也是为什么可以直接通过类名.方法名调用的原因。
    它们在占用内存时的区别:静态方法在程序开始时生成内存,实例方法在程序运行中生成内存。所以静态方法可以直接调用,实例方法要先生成实例才能调用。静态方法速度很快,但是多了会占内存

三.内部类

  • 定义:一个类内可以嵌套另一个类
class OuterClass {   // 外部类
    // ...
    class NestedClass { // 嵌套类,或称为内部类
        // ...
    }
}

1.实例内部类:
实例内部类是一个类中嵌套着另外一个类。 它有访问外部类成员的权限, 通常被称为内部类。
由于内部类嵌套在外部类中,因此必须首先实例化外部类,然后创建内部类的对象来实现。

2.静态内部类:
静态内部类可以使用 static 关键字定义,静态内部类我们不需要创建外部类来访问,可以直接访问它。

class OuterClass {
  int x = 10;

  static class InnerClass {
    int y = 5;
  }
}

public class MyMainClass {
  public static void main(String[] args) {
    OuterClass.InnerClass myInner = new OuterClass.InnerClass();
    System.out.println(myInner.y);
  }
}

输出结果为 5

注:静态内部类无法访问外部成员

四.设计模式

后续补充,本人没做过多了解

五.单例模式

  • 一个类只有一个实例
    应用介绍:
    意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

主要解决:一个全局使用的类频繁地创建与销毁。

何时使用:当您想控制实例数目,节省系统资源的时候。

如何解决:判断系统是否已经有这个单例,如果有则返回,如果没有则创建。

关键代码:构造函数是私有的。
1.懒汉式:线程不安全

public class Singleton {  
    private static Singleton instance;  
    private Singleton (){}  
  
    public static Singleton getInstance() {  
        if (instance == null) {  
            instance = new Singleton();  
        }  
        return instance;  
    }  
}

这种方式是最基本的实现方式,这种实现最大的问题就是不支持多线程。因为没有加锁 synchronized,所以严格意义上它并不算单例模式。这种方式 lazy loading 很明显,不要求线程安全,在多线程不能正常工作。
2.饿汉式:线程安全

public class Singleton {  
    private static Singleton instance = new Singleton();  
    private Singleton (){}  
    public static Singleton getInstance() {  
    return instance;  
    }  
}

这种方式比较常用,但容易产生垃圾对象。
优点:没有加锁,执行效率会提高。
缺点:类加载时就初始化,浪费内存。
它基于 classloader 机制避免了多线程的同步问题,不过,instance 在类装载时就实例化,虽然导致类装载的原因有很多种,在单例模式中大多数都是调用 getInstance 方法, 但是也不能确定有其他的方式(或者其他的静态方法)导致类装载,这时候初始化 instance 显然没有达到 lazy loading 的效果。

posted @ 2022-07-27 23:09  微曲酒  阅读(29)  评论(0)    收藏  举报