番石榴加入第3个参数NULL

时间:2015-02-10 10:00:30

标签: java nullpointerexception guava

谁可以解释一下这个?

 public final String join(@Nullable Object first, @Nullable Object second,Object... rest) {
        return this.join((Iterable)iterable(first, second, rest));
    }

private static Iterable<Object> iterable(final Object first, final Object second, final Object[] rest) {
        Preconditions.checkNotNull(rest);
        return new AbstractList() {
            public int size() {
                return rest.length + 2;
            }

            public Object get(int index) {
                switch(index) {
                case 0:
                    return first;
                case 1:
                    return second;
                default:
                    return rest[index - 2];
                }
            }
        };
    }

为什么方法连接不是这样的 - join(Object ... args)??? 其实如果我有一些例子:

String firstName = "John";
String lastName = "Doe";

public String getFullName(){
   return Joiner.on(" ").skipNulls().join(first, lastName, null);
}

发生NullPointerException!看起来很奇怪。 但是如果我调用:

String firstName = "John";
String lastName = "Doe";
String parentName = null;

  public String getFullName(){
       return Joiner.on(" ").skipNulls().join(first, lastName, parentName);
    }

输出:John Doe。

2 个答案:

答案 0 :(得分:3)

方法

join(@Nullable Object first, @Nullable Object second, Object... rest)

最后一个参数rest是一个Object数组,即Object[]

在第一种情况下:

join(first, lastName, null)

当你使用null时,无法知道它是什么类型,因此它被假定为(Object[])(因为它与方法签名匹配)所以参数{{1是} rest

第二个示例nullparentName所以:

String

相当于:

join(first, lastName, parentName)

其中join(first, lastName, (String) null) 不属于rest类型。因为它没有直接匹配Object[]Object...),所以它被转换为Object[]rest[0] null的一个位置的数组})

查看此示例:http://ideone.com/PPwU05

rest = [null]

输出是:

public static void main (String[] args) throws java.lang.Exception
{
    varargs(null);
    varargs((String) null);
    varargs(new String[]{"Hi!"});
    varargs();
}

public static void varargs (Object... array) {
    if (array == null) {
        System.out.println("Is null");
    } else {
        System.out.println(Arrays.toString(array));
    }
}

答案 1 :(得分:3)

  

为什么签名不是join(Object... args)

仅仅因为Guava团队希望您确保实际加入对象。要做到这一点,您至少需要2个参数。因此,前两个参数在运行时不会被异常检查,但在编译时会明确强制您使用多个对象。

所以这是一种强迫你正确写作的设计。实际上,副作用是,在没有异常的情况下,您无法将null添加为第三个参数。如果您想明确使用varargs并使用null,请写下以下内容:

Joiner joiner = ...
joiner.join(Arrays.asList(firstName, lastName, null));