zoukankan      html  css  js  c++  java
  • 用于避免bean对象连点方法调用报空指针异常,排查困难。

    import java.util.List;
    import java.util.Objects;
    import java.util.function.Function;
    
    public class ObjectUtil {
    
        private ObjectUtil() {}
    
        /**
         * 解决bean连点导致空指针异常错误难排查问题。具体使用方法看测试用例
         * @param <R>
         */
        public static class NoNullObject<R> {
    
            private StringBuilder sb;
    
            private R r;
    
            public static <R> NoNullObject<R> build(R r) {
                return new NoNullObject(r);
            }
    
            private NoNullObject(R r) {
                Objects.requireNonNull(r);
                this.r = r;
                sb = new StringBuilder();
                sb.append(r.getClass());
            }
    
            private NoNullObject(R r, StringBuilder sb) {
                this.sb = sb;
                this.r = r;
                if(r == null) {
                    throw new NullPointerException(sb.toString());
                }
            }
    
            public <V> NoNullObject<V> then(Function<? super R, ? extends V> after, String functionName) {
                Objects.requireNonNull(after);
                sb.append('.');
                sb.append(functionName);
                return new NoNullObject<>(after.apply(r), sb);
            }
    
            public <V> NoNullObject<V> listThen(Function<? super R, ? extends V> after, int index) {
                Objects.requireNonNull(after);
                List l = (List) r;
                if(index < 0) {
                    throw new RuntimeException("index must not < 0");
                }
                if(l.size() <= index) {
                    throw new RuntimeException(sb.toString() + " List size(" + l.size() + ") not <= index(" + index + ")");
                }
                sb.append('.');
                sb.append("get("+ index +")");
                return new NoNullObject<>(after.apply(r), sb);
            }
    
            public R getResult() {
                return r;
            }
    
        }
    
    
        /**
         * 解决bean连点导致空指针异常错误难排查问题。具体使用方法看测试用例
         * @param <T>
         * @param <R>
         */
        public interface NoNullFunction<T, R> {
    
            R apply(T t);
    
            static <T> NoNullFunction<T, T> identity(StringBuilder sb) {
                return t -> {
                    sb.append(t.getClass().getName());
                    return t;
                };
            }
    
            default <V> NoNullFunction<T, V> then(Function<? super R, ? extends V> after, StringBuilder sb, String functionName) {
                Objects.requireNonNull(after);
                return (T t) -> {
                    R r = apply(t);
                    if(r == null) {
                        throw new NullPointerException(sb.toString());
                    }
                    sb.append('.');
                    sb.append(functionName);
                    return after.apply(r);
                };
            }
    
            default <V> NoNullFunction<T, V> listThen(Function<? super R, ? extends V> after, int index, StringBuilder sb) {
                Objects.requireNonNull(after);
                return (T t) -> {
                    R r = apply(t);
                    //使用不规范这里很可能转换失败。
                    List l = (List) r;
                    if(r == null) {
                        throw new NullPointerException(sb.toString());
                    }
                    if(index < 0) {
                        throw new RuntimeException("index must not < 0");
                    }
                    if(l.size() <= index) {
                        throw new RuntimeException(sb.toString() + " List size(" + l.size() + ") not <= index(" + index + ")");
                    }
                    sb.append('.');
                    sb.append("get("+ index +")");
                    return after.apply(r);
                };
            }
        }
    
        /**
         * @param o
         * @param f
         * @param <T>
         * @return
         */
        public static <T, R> R noNullFunctionGet(T o, NoNullFunction<T,R> f, StringBuilder sb) {
            if(f == null || o == null) {
                throw new NullPointerException("f and o must not null!");
            }
            R r = f.apply(o);
            if(r == null) {
                throw new NullPointerException(sb.toString());
            }
            return r;
        }
    
    } 

    下面是使用方式

    对于数组的下标取值可能报的异常,需要个人在Function里进行处理

        @Test
        public void test1() {
            Order o = new Order();
            OrderPackage p = new OrderPackage();
            o.setPackages(new ArrayList<>());
            o.setPackages(Collections.singletonList(p));
            p.setLogisticsNumber("123456");
    
            ObjectUtil.NoNullObject<String> nno = ((ObjectUtil.NoNullObject<Order>) new ObjectUtil.NoNullObject(o))
                    .then(a -> a.getPackages(), "getPackages()")
                    .listThen(a -> a.get(0), 0)
                    .then(a -> a.getLogisticsNumber(), "getLogisticsNumber()");
    
            System.out.println(nno.getResult());
        }
    
        @Test
        public void test() {
            Order o = new Order();
            OrderPackage p = new OrderPackage();
    //        o.setPackages(new ArrayList<>());
    //        o.setPackages(Collections.singletonList(p));
    //        p.setLogisticsNumber("123456");
    
            //后面可以写一个生成代码程序,将o.getPackages().get(O).getLogisticsNumber() 转换为下面代码
            StringBuilder sb = new StringBuilder();
            ObjectUtil.NoNullFunction<Order, Order> f = ObjectUtil.NoNullFunction.identity(sb);
            ObjectUtil.NoNullFunction<Order, String> r =
                    f.then(a -> a.getPackages(), sb,"getPackages()")
                        .listThen(a -> a.get(0), 0,  sb)
                        .then(a -> a.getLogisticsNumber(),  sb,"getLogisticsNumber()");
    
            String result = ObjectUtil.noNullFunctionGet(o, r, sb);
            System.out.println(result);
        }
  • 相关阅读:
    [LeetCode] Lowest Common Ancestor of a Binary Search Tree
    [LeetCode] Palindrome Linked List
    Android控件开发之Chronometer(转)
    andriod 动态设置TextView 和 RelativeLayou 高度
    android RelativeLayout 动态设置高度
    android 判断字符串是否为空与比对["=="与equals()的区别]
    android 实现ImageView按压效果和解决背景图片拉申问题
    android XML布局 属性与运用
    android 解决.XML提示ava.lang.NullPointerException at错误后XML没显示
    Android设置AlertDialog点击按钮对话框不关闭(转)
  • 原文地址:https://www.cnblogs.com/math-and-it/p/14912923.html
Copyright © 2011-2022 走看看