1 問題引出
(1)緣由
最近在研究如何在項目中引入Redis緩存,於是遇到可變參數這個疑惑點,之前沒有好好研究過,為了避免項目后期出現問題。
(2)項目相關技術
- SpringBoot
- Redis
- Kryo(數據存儲使用二進制)
(3)疑惑點:
-
概述:Redis設置List時,如果rightPushAll方法,可能發生空指針異常
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Test
public void test(){
// 發生空指針異常
redisTemplate.opsForList().rightPushAll("test",null);
}
-
源碼
public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperations<K, V>, BeanClassLoaderAware {
public ListOperations<K, V> opsForList() {
if (listOps == null) {
listOps = new DefaultListOperations<K, V>(this);
}
return listOps;
}
}
class DefaultListOperations<K, V> extends AbstractOperations<K, V> implements ListOperations<K, V> {
public Long rightPushAll(K key, V... values) {
final byte[] rawKey = rawKey(key);
final byte[][] rawValues = rawValues(values);
return execute(new RedisCallback<Long>() {
public Long doInRedis(RedisConnection connection) {
return connection.rPush(rawKey, rawValues);
}
}, true);
}
}
abstract class AbstractOperations<K, V> {
byte[][] rawValues(Object... values) {
final byte[][] rawValues = new byte[values.length][];
int i = 0;
for (Object value : values) {
rawValues[i++] = rawValue(value);
}
return rawValues;
}
}
2 可變參數簡單研究
(1)概述
- 可變參數能夠接受0個參數
- 可變參數能夠接受1個參數
- 可變參數能夠接受多個參數
(2)DEMO
-
0個參數
public static void main(String[] args) {
test();
}
private static void test(Object... values) {
System.out.println(values.getClass()); // class [Ljava.lang.Object;
System.out.println(values.length); // 0
}
-
1個參數
// test1
public static void main(String[] args) {
test(1); // 1
}
// test2
public static void main(String[] args) {
test(null); // Exception in thread "main" java.lang.NullPointerException
}
// test3:這種
public static void main(String[] args) {
Object[] objects = new Object[]{null};
test(objects); // 1,不報異常了
}
private static void test(Object... values) {
System.out.println(values.getClass()); // class [Ljava.lang.Object;
System.out.println(values.length);
}
-
多個參數
public static void main(String[] args) {
test(1,2,3,"Test"); // 打印輸出:1 2 3 Test
}
private static void test(Object... values) {
int length = values.length;
if (values == null && length == 0) return;
Object[] localValues = new Object[length];
System.arraycopy(values, 0, localValues, 0, length);
for (Object obj : localValues) {
System.out.println(obj);
}
}
3 結論
- 使用可變參數需要檢查參數是否為null
- 可變參數內部使用數組實現
- 多個參數時,最好在方法內部復制一份副本,防止外部修改了參數
注:以后把字節碼打印出來補充