java方法可變參數研究


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
  • 可變參數內部使用數組實現
  • 多個參數時,最好在方法內部復制一份副本,防止外部修改了參數

注:以后把字節碼打印出來補充


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM