Java基础知识(总结)

设计模式

1.单例模式的实现方法:

(1)饿汉模式:不管是否使用到该类,都先初始化该类,有可能会造成资源浪费! 线程安全,调用效率高,但是不能延时加载 !

public class Singleton{
 //类初始化时,立即加载该对象(没有延时加载的优势)!由于加载类时,天然的线程安全!
    private static Singleton instance=new Singleton();
    
    //私有构造器
    private Singleton(){
    }

    public static Singleton getInstance{
        return instance;
    }
    
}

(2)懒汉模式:

方式1:

这种写法只能在单线程下使用。如果是多线程,可能发生一个线程通过并进入了 if (singleton == null) 判断语句块,但还未来得及创建新的实例时,另一个线程也通过了这个判断语句,两个线程最终都进行了创建,导致多个实例的产生。所以在多线程环境下必须摒弃此方式。 

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

} 

方法2:线程安全,调用效率不高,并且可以延时加载 

通过为 getInstence() 方法增加 synchronized 关键字,迫使每个线程在进入这个方法前,要先等候别的线程离开该方法,即不会有两个线程可以同时进入此方法执行 new Singleton(),从而保证了单例的有效。但它的致命缺陷是效率太低了,每个线程每次执行 getInstance() 方法获取类的实例时,都会进行同步。而事实上实例创建完成后,同步就变为不必要的开销了,这样做在高并发下必然会拖垮性能。所以此方法虽然可行但也不推荐。 

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

方法3:双重检查锁式:由于JVM底层内部模型原因,偶尔会出问题,不建议使用

public class Signalton{
    private static Signalton instance;
    
    private Signalton(){
    }

    public static Signalton getInstance(){
        if(instance==null)
            synchronized(Signalton.class){
                instance=new Signalton();
            }
        return instance;
    }
}

方法4:静态内部类:线程安全,调用效率高,并且可以延时加载。推荐使用 

这种方式是Singleton 类被装载了,instance不一定被初始化。因为SingletonClassGetInstance 类没有被主动使用,只有显示通过调用getInstance方法时,才会显示装载SingletonClassGetInstance 类,从而实例化instance。

public class Signalton{
    //静态内部类
    private static class SingletonClassGetInstance{
        public static final Signalton instance = new Signalton();
    }
    // 私有构造器
    private Signalton() {
    }

    public static  Signalton getInstance() {
        return SingletonClassGetInstance.instance;
    }
    
}

方法5:枚举:线程安全,调用效率高,不能延时加载,但是可以天然的防止反射和反序列化漏洞

这种模式下,线程安全,调用效率高,但是不能延时加载!实际工作中,少有人使用这种方式!

public Enum Signalton{
    //这个枚举对象本身就是单例对象
    INSTANCE;
    //添加自己需要的操作
    public void operation(){
    }
}

注:单例模式中的存在的问题:如果单例类实现了java.io.Serializable接口,那么这个类可能会被反序列化,并且反序列化多次同一对象时,会得到多个单例类的实例。这样就不是单例了! 

枚举单例是如何被保证的:

  • 首先,在枚举中我们明确了构造方法限制为私有,在我们访问枚举实例时会执行构造方法。
  • 同时每个枚举实例都是 static final 类型的,也就表明只能被实例化一次。

2.工厂设计模式

反射

1.什么是反射?类的反射的安全问题

java特性

1.封装的基本原理

2.多态?多态的好处?

数据内存分配

1.int a=5,a=10,a=15;在内存中产生的数据?

一个。

2.a="Hello";a+="world";a=+"!";产生几个对象?

String 是final,共产生三个对象。

3.String内存分配

  • String常量池:存放string对象实例
  • 对于String s=“hhh”,首先去常量池中查看是否有string对象的值为“hhh”的实例,如果有直接将s指向该常量池中的对象实例;如果没有,在常量池中创建值为“hhh”的对象实例,并使s指向它。
  • 对于String s=new String(“hhh”),首先去常量池中查看是否有string对象的值为“hhh”的实例,如果没有,在常量池中创建值为“hhh”的对象实例;如果有对常量池不做任何操作。然后也在堆中创建一个值为“hhh”的对象实例,并使s指向堆中的实例。

4.基本类型的内存分配以及基本类型的包装类的内存分配

基本类型和基本类型的包装类。基本类型有:byte、short、char、int、long、boolean。基本类型的包装类分别是:Byte、Short、Character、Integer、Long、Boolean。注意区分大小写。二者的区别是:基本类型体现在程序中是普通变量,基本类型的包装类是类,体现在程序中是引用变量。因此二者在内存中的存储位置不同:基本类型存储在栈中,而基本类型包装类存储在堆中。上边提到的这些包装类都实现了常量池技术,另外两种浮点数类型的包装类则没有实现。

  • 对于Integer包装类,维护一个常量池
    • 当使用Integer a=1时,首先

stringbuffer和stringbuild

Java的值传递和引用传递

java中只有值传递。

参考:https://juejin.im/post/5bce68226fb9a05ce46a0476

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值