victory的博客

长安一片月,万户捣衣声

0%

强软弱虚四大引用

import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

class StudentClass{
    @Override
    protected void finalize() throws Throwable{
        System.out.println("student对象被回收了");
    }
}

public class ReferencesTest {
    public static void main(String[] args) {
        
        /**
         * 强引用
         * 只要某个对象有强引用与之关联,这个对象永远不会被回收,即使内存不足,JVM宁愿抛出OOM,也不会去回收。
         */
        //StudentClass student = new StudentClass();
        //student = null;//断开强引用与对象之间的关联
        //System.gc();
        
        
        /**
         * 软引用
         * 内存不足时,JVM会回收软引用关联的对象
         * 
         * 比较适合用作缓存,当内存足够,可以正常的拿到缓存,当内存不够,就会先干掉缓存,不至于马上抛出OOM。
         */
//        SoftReference<byte[]> softReference = new SoftReference<byte[]>(new byte[1024*1024*10]);
//        System.out.println(softReference.get());
//        System.gc();
//        System.out.println(softReference.get());
//        byte[] bytes = new byte[1024 * 1024 * 10];
//        System.out.println(softReference.get());
        
        /**
         * 弱引用
         * 不管内存是否足够,只要发生GC,都会被回收
         */
//        WeakReference<byte[]> weakReference = new WeakReference<byte[]>(new byte[1]);
//        System.out.println(weakReference.get());
//        System.gc();
//        System.out.println(weakReference.get());
        
//        [B@15db9742
//         null
        
        /**
         * 虚引用
         * 特点一:无法通过虚引用来获取对一个对象的真实引用
         * 特点二:虚引用必须与ReferenceQueue一起使用,当GC准备回收一个对象,如果发现它还有虚引用,就会在回收之前,把这个虚引用加入到与之关联的ReferenceQueue中。
         * 
         * 
         * Unlike soft and weak references, phantom references are not
 automatically cleared by the garbage collector as they are enqueued.  An
object that is reachable via phantom references will remain so until all
such references are cleared or themselves become unreachable.
         */
        ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
        List<byte[]> bytes = new ArrayList<>();
        PhantomReference<StudentClass> reference = new PhantomReference<StudentClass>(new StudentClass(),referenceQueue);
        
        new Thread(() -> {
            for (int i = 0; i < 100;i++ ) {
                bytes.add(new byte[1024 * 1024]);
            }
        }).start();
 
        new Thread(() -> {
            while (true) {
                Reference poll = referenceQueue.poll();
                if (poll != null) {
                    System.out.println("虚引用被回收了:" + poll);
                }
            }
        }).start();
        Scanner scanner = new Scanner(System.in);
        scanner.hasNext();
    }
}

单例模式

单例模式(Singleton),保证一个类有一个实例,并提供一个访问它的全局访问点。

“通常我们可以让一个全局变量使得一个对象被访问,但它不能防止你实例化多个对象。一个最好的办法就是,让类自身保存
它的唯一实例。这个类可以保证没有其他实例可以被创建,并且它可以提供一个访问该实例的方法。

阅读全文 »

工厂方法模式

why 工厂方法模式?
简单工厂模式违背了开放封闭原则(开放了拓展,也开放了修改),如果需要增加功能就需要在工厂类中修改逻辑判断,于是工厂方法模式应运而生。

工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法是一个类的实例化延迟到子类。

阅读全文 »

简单工厂模式

工厂:用一个单独的类来完成创造实例的过程。
案例
类图:

class Operation{
    private double numberA = 0;
    private double numberB = 0;
    public double getNumberA() {
        return numberA;
    }
    public void setNumberA(double numberA) {
        this.numberA = numberA;
    }
    public double getNumberB() {
        return numberB;
    }
    public void setNumberB(double numberB) {
        this.numberB = numberB;
    }
    public double getResult() throws Exception{
        double result = 0;
        return result;
    }
}

class Add extends Operation{
    public double getResult()
    {
        double result = 0;
        result = getNumberA() + getNumberB();
        return result;
    }
}

class Sub extends Operation{
    public double getResult()
    {
        double result = 0;
        result = getNumberA() - getNumberB();
        return result;
    }
}

class Mul extends Operation{
    public double getResult()
    {
        double result = 0;
        result = getNumberA() * getNumberB();
        return result;
    }
}

class Div extends Operation{
    public double getResult() throws Exception
    {
        double result = 0;
        if (getNumberB() == 0){
            throw new Exception("除数不能为0");
        }
        result = getNumberA() / getNumberB();
        return result;
    }
}

//工厂:用一个单独的类来做这个创造实例的过程
class OperationFactory{
    public static Operation createOperate(String operate){
        Operation oper = null;
        
        if(operate.equals("+")){
            oper = new Add();
        }else if(operate.equals("-")){
            oper = new Sub();
        }else if(operate.equals("*")){
            oper = new Mul();
        }else if(operate.equals("/")){
            oper = new Div();
        }
        return oper;
    }
}

public class SimpleFactoryTest {
    public static void main(String[] args) throws Exception {
        Operation oper = OperationFactory.createOperate("+");
        oper.setNumberA(1);
        oper.setNumberB(2);
        double result = oper.getResult();
        System.out.println(result);
    }
}

在使用简单工厂模式的情况下,如果我们要增加新的功能,比如说现在要增加一个求余操作,
我们需要增加一个用于求余运算的类,然后在OperationFactory中增加对于求余运算的逻辑判断,这样的做法违背了
开放封闭原则,即在开放拓展的同时也开放了修改。

class Mod extends Operation{
    public double getResult(){
        double result = 0;
        result = getNumberA() % getNumberB();
        return result;
    }
}

class OperationFactory{
    public static Operation createOperate(String operate){
        ......
        else if(operate.equals("%")){
            oper = new Div();
        }
        ......
    }
}

spring和springMVC的整合

1、不整合:需要将spring所管理的内容都交给springMVC管理,这样会造成业务逻辑混乱
2、整合:spring的配置文件什么时候加载?怎么加载?
解决办法:监听器,可以在ServletContext加载时,通过监听器加载spring的配置文件,创建spring容器
spring提供的监听器:ContextLoaderListener
3、bean被创建两次的问题:在springMVC中只扫描控制层,在spring中,通过包含或排除对所扫描的包进行指定
4、spring和springMVC的关系
spring是父容器
springMVC是子容器
规定:子容器能够调用父容器的bean,而父容器不能够调用访问子容器中的bean

阅读全文 »

异常处理

1.在SpringMVC配置文件(springMVC.xml)中做以下配置:

<!-- 异常处理 -->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <property name="exceptionMappings">
        <props>
            <prop key="java.lang.NullPointerException">error</prop>
        </props>
    </property>
</bean>
阅读全文 »

拦截器 HandlerInterceptor

1.在SpringMVC配置文件(springMVC.xml)中进行以下配置:

<mvc:interceptors>
    <!-- 默认拦截所有请求 -->
    <!-- 第一种方式 -->
    <bean class="com.atguigu.interceptor.FirstInterceptor"></bean>
    <bean class="com.atguigu.interceptor.SecondInterceptor"></bean>
    <!-- 
        第二种方式
        此方式要求拦截器上必须加注解@Component
     -->
    <!-- <ref bean="firstInterceptor" /> -->
    
    <!-- 设置自定义拦截方式 -->
    <!-- <mvc:interceptor>
        <bean></bean>
        <mvc:mapping path=""/>
        <mvc:exclude-mapping path=""/>
    </mvc:interceptor> -->
</mvc:interceptors>
阅读全文 »