• 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
    • 可变参数内部使用数组实现
    • 多个参数时,最好在方法内部复制一份副本,防止外部修改了参数

    注:以后把字节码打印出来补充

  • 相关阅读:
    手势识别 ios
    无题
    核心动画笔记
    Quartz2D的学习2
    Quartz2D的学习1
    NSURLsessionTask
    NSURLSession
    POST请求的两种方式
    网络第一天
    NSThread
  • 原文地址:https://www.cnblogs.com/linzhanfly/p/9849788.html
Copyright © 2020-2023  润新知