Java教程

Java中关键字-instanceof-的真实应用场景-2022新项目

本文主要是介绍Java中关键字-instanceof-的真实应用场景-2022新项目,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

instanceof关键字主要用来判断两个对象是否为同一种类型,举个例子如果有猫类、动物类,猫类继承自动物类;

判断某个类是否为动物类,就可以使用instanceof关键字。下面简单介绍几种真实的应用场景.

场景一:工具类中判断某个类是否为null或者是为空;代码如下:

    public static boolean judgmentObjectIsEmpty(Object object) {

        if (object == null) {

            return true;

        }

        if (object instanceof Map) {

            Map map = (Map)object;

            return map.isEmpty();

        } else if (object instanceof List) {

            List list = (List)object;

            return list.isEmpty();

        } else if (object instanceof String) {

            String str = (String)object;

            return "null".equals(str) || "".equals(str);

        }

        return false;

}

Instanceof 主要用于判断任意一个类是否为Map集合、List集合、String字符串。

场景二:过滤器中使用自定义增强的request请求,在强制转换前先判断一下是否属于同一种类型;

public class BodyReaderFilter implements Filter {

    @Override

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {

        ServletRequest requestWrapper = null;

        if (request instanceof HttpServletRequest) {

            requestWrapper = new BodyReaderWrapper((HttpServletRequest)request);

        }

 

        if (requestWrapper == null) {

            filterChain.doFilter(request, response);

        } else {

            filterChain.doFilter(requestWrapper, response);

        }

    }

}

 

import org.springframework.util.StreamUtils;

 

import javax.servlet.ReadListener;

import javax.servlet.ServletInputStream;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletRequestWrapper;

import java.io.BufferedReader;

import java.io.ByteArrayInputStream;

import java.io.IOException;

import java.io.InputStreamReader;

 

/**

 * @Description: 自定义 request 增强类,解决在一次请求中输入流只能获取一次请求参数的问题

 * @ClassName: BodyReaderWrapper

 * @author: dengchao

 * @date: 2021/8/18 15:43

 */

 

public class BodyReaderWrapper extends HttpServletRequestWrapper{

    //用于将流保存下来

    private byte[] requestBody;

 

    public BodyReaderWrapper(HttpServletRequest request) throws IOException {

        super(request);

        //2021-10-19 将从请求头中获取的token请求信息放到 请求体中

        String tempToken = request.getHeader("loginToken");

        System.out.println("从请求头中获取的token信息8585--->" + tempToken);

        request.setAttribute("loginToken", tempToken);

        requestBody = StreamUtils.copyToByteArray(request.getInputStream());

    }

 

    @Override

    public ServletInputStream getInputStream() throws IOException {

 

        final ByteArrayInputStream bais = new ByteArrayInputStream(requestBody);

 

        return new ServletInputStream() {

 

            @Override

            public int read() throws IOException {

                return bais.read();

            }

 

            @Override

            public boolean isFinished() {

                return false;

            }

 

            @Override

            public boolean isReady() {

                return false;

            }

 

            @Override

            public void setReadListener(ReadListener readListener) {

            }

        };

    }

 

    @Override

    public BufferedReader getReader() throws IOException {

        return new BufferedReader(new InputStreamReader(getInputStream()));

    }

}

场景三: 自定义注解中用于校验时使用;

/**

 * 枚举校验注解

 */

@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})

@Retention(RUNTIME)

@Documented

@Constraint(validatedBy = {EnumValueValidator.class})

public @interface EnumValue {

 

    // 默认错误消息

    String message() default "必须为指定值";

 

    String[] strValues() default {};

 

    int[] intValues() default {};

 

    // 分组

    Class<?>[] groups() default {};

 

    // 负载

    Class<? extends Payload>[] payload() default {};

 

    // 指定多个时使用

    @Target({FIELD, METHOD, PARAMETER, ANNOTATION_TYPE})

    @Retention(RUNTIME)

    @Documented

    @interface List {

        EnumValue[] value();

    }

}

 

public class EnumValueValidator implements ConstraintValidator<EnumValue, Object> {

    private String[] strValues;

    private int[] intValues;

    @Override

    public void initialize(EnumValue constraintAnnotation) {

        strValues = constraintAnnotation.strValues();

        intValues = constraintAnnotation.intValues();

    }

 

    @Override

    public boolean isValid(Object value, ConstraintValidatorContext context) {

        if (value instanceof String) {

            for (String s : strValues) {

                if (s.equals(value)) {

                    return true;

                }

            }

        } else if (value instanceof Integer) {

            for (int s : intValues) {

                if (s == ((Integer) value).intValue()) {

                    return true;

                }

            }

        }

        return false;

    }

}

这个是注解的作用是校验某些固定的参数值,可以是整数或者字符串。注解在处理的时候使用到instanceof这个关键字,

主要用于判断一个Object对象是String字符串类型还是Integer类型,这个注解已经在项目中使用起来;参考文章:

https://www.cnblogs.com/pojo/p/15054698.html

场景四:JSON转换工具类中使用;

    /**

     * 对象转化为json字符串

     * @param obj 待转化对象

     * @return 代表该对象的Json字符串

     */

    public static final String toJson(final Object obj) {

        //当参数为String类型 直接返回该字符串

        if(obj instanceof String){

            return (String)obj;

        }

        return JSON.toJSONString(obj);

}

这个地方使用的时候,先判断一下需要转换的对象是否为String类型,如果是则直接返回,如果不是在使用JSON进行转换。

场景五: 判断某两个异常是否为同一种异常类型;

    @ExceptionHandler(value = Exception.class)

    public ResponseEntity<JsonResult<Object>> baseErrorHandler(Exception ex) {

        JsonResult<Object> r = new JsonResult<>();

        if (ex instanceof BaseException || ex.getClass().isAssignableFrom(BaseException.class)) {

            r.declareFailure((BaseException) ex, null);

            logger.error(((BaseException) ex).getErrorMessage(), ex);

        } else {

            r.declareFailure(MessageConstant.A000001, "系统未知异常,服务无法正常使用", null);

            logger.error(ex.getMessage(), ex);

        }

        return ResponseEntity.ok(r);

    }

场景六:使用JSONObject或者JSONArray的时候,类型转换前先进行类型的判断;

    Object record = data.getRecords();

                    String erCode = "";

                    String erMsg = "";

                    if(record instanceof JSONObject) {

                        erCode = ((JSONObject) record).getString("erCode");

                        erMsg = ((JSONObject) record).getString("erMsg");

                    } else if (record instanceof JSONArray && ((JSONArray) record).size() > 0){

                        Object obj = ((JSONArray) record).get(0);

                        erCode = ((JSONObject) obj).getString("erCode");

                        erMsg = ((JSONObject) obj).getString("erMsg");

                    }

待转换的数据有可能是单个对象,也有可能是数组,这种处理方式可以避免类型转换异常而出现错误。

总结: instanceof关键字一般主要用于包装类在进行强制转换之前,先判断一下需要转换的两个类是否为同一种类型,如果是则

可以进行强制转换,如果不是则做其他处理。这样处理的好处是可以大概率的避免出现类型转换异常,

java.lang.ClassCastException。之前在开发中就曾出现过这个异常,在使用Mybatis中自定义的拦截器的时候,参数转换出现

异常,导致请求时频繁出现异常。大致错误就是就是参数不能直接转换为HashMap,解决办法就是使用instanceof判断一下

参数instanceof HashMap,如果是则转换为HashMap集合,然后直接从集合里面取数据。不是的话就转换为其他类型,这样

就很好的解决掉BUG.

这篇关于Java中关键字-instanceof-的真实应用场景-2022新项目的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!