java变参
java变参是通过数组来实现的
Object[] addAll(Object[] array1, Object... array2)和Object[] addAll(Object[] array1, Object[] array2)签名应该一致的。
public class ArrayUtils {
    // Clone
    // -----------------------------------------------------------------------
    /**
     * <p>
     * Shallow clones an array returning a typecast result and handling <code>null</code>.
     * </p>
     *
     * <p>
     * The objects in the array are not cloned, thus there is no special handling for multi-dimensional arrays.
     * </p>
     *
     * <p>
     * This method returns <code>null</code> for a <code>null</code> input array.
     * </p>
     *
     * @param array
     *            the array to shallow clone, may be <code>null</code>
     * @return the cloned array, <code>null</code> if <code>null</code> input
     */
    public static Object[] clone(Object[] array) {
        if (array == null) {
            return null;
        }
        return array.clone();
    }
/**
     * <p>
     * Adds all the elements of the given arrays into a new array.
     * </p>
     * <p>
     * The new array contains all of the element of <code>array1</code> followed by all of the elements <code>array2</code>.
     * When an array is returned, it is always a new array.
     * </p>
     *
     * <pre>
     * ArrayUtils.addAll(null, null)     = null
     * ArrayUtils.addAll(array1, null)   = cloned copy of array1
     * ArrayUtils.addAll(null, array2)   = cloned copy of array2
     * ArrayUtils.addAll([], [])         = []
     * ArrayUtils.addAll([null], [null]) = [null, null]
     * ArrayUtils.addAll(["a", "b", "c"], ["1", "2", "3"]) = ["a", "b", "c", "1", "2", "3"]
     * </pre>
     *
     * @param array1
     *            the first array whose elements are added to the new array, may be <code>null</code>
     * @param array2
     *            the second array whose elements are added to the new array, may be <code>null</code>
     * @return The new array, <code>null</code> if <code>null</code> array inputs. The type of the new array is the type of the
     *         first array.
     * @since 2.1
     */
    public static Object[] addAll(Object[] array1, Object... array2) {
        if (array1 == null) {
            return clone(array2);
        } else if (array2 == null) {
            return clone(array1);
        }
        Object[] joinedArray = (Object[]) Array
                .newInstance(array1.getClass().getComponentType(), array1.length + array2.length);
        System.arraycopy(array1, , joinedArray, , array1.length);
        System.arraycopy(array2, , joinedArray, array1.length, array2.length);
        return joinedArray;
    }
    /**
     * Swaps the two specified elements in the specified array.
     *
     * @param arr
     * @param i
     * @param j
     */
    public static void swap(Object[] arr, int i, int j) {
        Object tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }
}
测试变参
 public static void main(String[] args) {
        String[] array = { "", "" };
        // The argument of type String[] should explicitly be cast to Object[] for the invocation of the varargs method
        // addAll(Object[], Object...) from type ArrayUtils. It could alternatively be cast to Object for a varargs invocation
        System.out.println(Arrays.toString(ArrayUtils.addAll(array, new String[] { "", "" }))); // Compile warning
        System.out.println(Arrays.toString(ArrayUtils.addAll(array, "", ""))); // OK
        System.out.println(Arrays.toString(ArrayUtils.addAll(array, (Object[]) new String[] { "", "" }))); // OK
        System.out.println(Arrays.toString(ArrayUtils.addAll(array, (Object) new String[] { "", "" })));// java.lang.ArrayStoreException
    }
自动包装
Object[] addAll(Object[] array1, Object... array2)
--> 传参:Object[] addAll(Object[] array1, Object array2_0, Object array2_1, Object array2_2, ...)
--> 变长参数包装:Object[] array2 = new Object[]{array2_0, array2_1, array2_2};
--> 编译后实际的:Object[] addAll(Object[] array1, Object[] array2)
由于实际函数是Object[] addAll(Object[] array1, Object[] array2),则在变长参数位置直接传递数组时,编译器给出警告。
- 默认的数组直接作为实际函数Object[] addAll(Object[] array1, Object[] array2)的第二参数,
- 消除警告可以添加强制转换,规定是(Object[])和默认方式相同;(Object)则作为变长参数的一项,自动包装为new Object[]{(Object) new String[] { "2", "6" }},变成了二维数组,String型数组不能存储元素String[]的对象(String[] joinedArray; joinedArray[0] = new String[] { "2", "6" }是不正确的),则在第二个System.arraycopy发生存储异常
另外的消除编译警告还可以这样,通过泛型:
    public static <T> Object[] addAll(Object[] array1, T... array2) {
        if (array1 == null) {
            return clone(array2);
        } else if (array2 == null) {
            return clone(array1);
        }
        Object[] joinedArray = (Object[]) Array
                .newInstance(array1.getClass().getComponentType(), array1.length + array2.length);
        System.arraycopy(array1, 0, joinedArray, 0, array1.length);
        System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
        return joinedArray;
    }
缺点是编译时如果array2类型不是全部一样,会被检查,如
String[] array = { "22", "66" };
System.out.println(Arrays.toString(ArrayUtils.addAll(array, new Object[] { "2", "6", 2 })));
System.out.println(Arrays.toString(ArrayUtils.addAll(array, "2", "6", 2))); 
继续执行,只会得到java.lang.ArrayStoreException。除非第一参数是Object[] array = { "22", "66" };才能即能存储String又能存储Integer(上面的2)
继续改造(版本高的ArrayUtils@github.com或ArrayUtils@grepcode.com貌似更好,但这里和它有点区别,使用两个泛型帮助严格类型检查):
/**
* <p>
* Shallow clones an array returning a typecast result and handling
* {@code null}.
* </p>
*
* <p>
* The objects in the array are not cloned, thus there is no special
* handling for multi-dimensional arrays.
* </p>
*
* <p>
* This method returns {@code null} for a {@code null} input array.
* </p>
*
* @param <T> the component type of the array
* @param array the array to shallow clone, may be {@code null}
* @return the cloned array, {@code null} if {@code null} input
*/
public static <T> T[] clone(final T[] array) {
if (array == null) {
return null;
}
return array.clone();
} /**
* <p>
* Adds all the elements of the given arrays into a new array.
* </p>
* <p>
* The new array contains all of the element of {@code array1} followed by
* all of the elements {@code array2}. When an array is returned, it is
* always a new array.
* </p>
*
* <pre>
* ArrayUtils.addAll(null, null) = null
* ArrayUtils.addAll(array1, null) = cloned copy of array1
* ArrayUtils.addAll(null, array2) = cloned copy of array2
* ArrayUtils.addAll([], []) = []
* ArrayUtils.addAll([null], [null]) = [null, null]
* ArrayUtils.addAll(["a", "b", "c"], ["1", "2", "3"]) = ["a", "b", "c", "1", "2", "3"]
*
* ArrayUtils.addAll(new Number[] { 1, 2 }, new Byte[] { 22 }) = Number[]{1, 2, 22};
* </pre>
*
* @param <T> the component type of the first array
* @param <E> the component type of the second array
*
* @param array1 the first array whose elements are added to the new array,
* may be {@code null}
* @param array2 the second array whose elements are added to the new array,
* may be {@code null}
* @return The new array, {@code null} if both arrays are {@code null}. The
* type of the new array is the type of the first array, unless the
* first array is null, in which case the type is the same as the
* second array.
* @since 2.1
* @throws IllegalArgumentException if the array types are incompatible
*/
@SafeVarargs
public static <T, E extends T> T[] addAll(T[] array1, E... array2) {
if (array1 == null) {
return clone(array2);
} else if (array2 == null) {
return clone(array1);
}
final Class<?> type1 = array1.getClass().getComponentType();
@SuppressWarnings("unchecked")
// OK, because array is of type T
final T[] joinedArray = (T[]) Array.newInstance(type1, array1.length + array2.length);
System.arraycopy(array1, 0, joinedArray, 0, array1.length);
try {
System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
} catch (final ArrayStoreException ase) {
// Check if problem was due to incompatible types
/*
* We do this here, rather than before the copy because: - it would
* be a wasted check most of the time - safer, in case check turns
* out to be too strict
*/
final Class<?> type2 = array2.getClass().getComponentType();
if (!type1.isAssignableFrom(type2)) {
throw new IllegalArgumentException("Cannot store " + type2.getName() + " in an array of "
+ type1.getName(), ase);
}
throw ase; // No, so rethrow original
}
return joinedArray;
}
缺点是有警告,当参数为null
// The argument of type null should explicitly be cast to Number[] for
// the invocation of the varargs method addAll(Number[], Number...) from
// type ArrayUtils. It could alternatively be cast to Number for a
// varargs invocation
Number[] nums = ArrayUtils.addAll(new Number[] { 1, 2, 3 }, null);
System.out.println(Arrays.toString(nums)); nums = ArrayUtils.addAll(new Number[] { 1, 2, 3 }, (Byte[]) null); // OK
System.out.println(Arrays.toString(nums)); String[] strs = ArrayUtils.addAll(null, new String[] { "22", "66", "88" });// OK
System.out.println(Arrays.toString(strs));
instanceof, isinstance,isAssignableFrom
Class<?> thisClass = Number.class;
Class<? extends Number> cls = Integer.class; System.out.println(thisClass.isAssignableFrom(cls)); // true
System.out.println(cls.isAssignableFrom(thisClass));// false Integer integer = Integer.valueOf(1);
Number number = integer;
Object objNumber = number;
System.out.println(integer instanceof Number); // true
// ERROR: Incompatible conditional operand types Integer and String
// System.out.println(integer instanceof String);
System.out.println(objNumber instanceof String);// false
instanceof
使用:AA instanceof BB,检查左边是否是右边的实例而返回boolean值。注意编译前会预判是否合法而提示Incompatible conditional operand types AA and BB。
请查看上例,number和integer以及objNumber都是指向同一个实例,而后两个检查是否是String类实例前者却报错。
boolean java.lang.Class.isAssignableFrom(Class<?> cls)
Determines if the class or interface represented by this
Classobject is either the same as, or is a superclass or superinterface of, the class or interface represented by the specifiedClassparameter. It returnstrueif so; otherwise it returnsfalse. If thisClassobject represents a primitive type, this method returnstrueif the specifiedClassparameter is exactly thisClassobject; otherwise it returnsfalse.Specifically, this method tests whether the type represented by the specified
Classparameter can be converted to the type represented by thisClassobject via an identity conversion or via a widening reference conversion. See The Java Language Specification, sections 5.1.1 and 5.1.4 , for details.
- Parameters:
- cls the
Classobject to be checked- Returns:
- the
booleanvalue indicating whether objects of the typeclscan be assigned to objects of this class- Throws:
- NullPointerException - if the specified Class parameter is null.
- Since:
- JDK1.1
中文
isAssignableFrom
public boolean isAssignableFrom(Class<?> cls)
- 判定此
Class对象所表示的类或接口与指定的Class参数所表示的类或接口是否相同,或是否是其超类或超接口。如果是则返回true;否则返回false。如果该Class表示一个基本类型,且指定的Class参数正是该Class对象,则该方法返回true;否则返回false。特别地,通过身份转换或扩展引用转换,此方法能测试指定
Class参数所表示的类型能否转换为此Class对象所表示的类型。有关详细信息,请参阅 Java Language Specification 的第 5.1.1 和 5.1.4 节。
- 参数:
cls- 要检查的Class对象- 返回:
- 表明
cls类型的对象能否赋予此类对象的boolean值- 抛出:
NullPointerException- 如果指定的 Class 参数为 null。- 从以下版本开始:
- JDK1.1
如果把一个超类和子类有继承实现关系看作有上下大小关系,则isAssignableFrom左边是上型超类右边是下型子类才返回true,被测对象类是入参对象类的超类,入参类的实例可以向上转型给被测对象类的实力。。。
中文
isInstance
public boolean isInstance(Object obj)
- 判定指定的
Object是否与此Class所表示的对象赋值兼容。此方法是 Java 语言instanceof运算符的动态等效方法。如果指定的Object参数非空,且能够在不引发ClassCastException的情况下被强制转换成该Class对象所表示的引用类型,则该方法返回 true;否则返回false。特别地,当该
Class对象表示一个已声明的类时,若指定的Object参数是所表示类(或其任一子类)的一个实例,则此方法返回true;否则返回false。如果此Class对象表示一个数组类,且通过身份转换或扩展引用转换,指定的Object参数能转换为一个数组类的对象,则返回true;否则返回false。如果此Class对象表示一个接口,且指定Object参数的类或任一超类实现了此接口,则此方法返回true;否则返回false。如果此Class对象表示一个基本类型,则此方法返回false。
- 参数:
obj- 要检查的对象- 返回:
- 如果
obj是此类的实例,则返回 true- 从以下版本开始:
- JDK1.1
字段隐藏,反射获取同名字段成员,getDeclaringClass得到字段所属声明类
public static void main(String[] args) throws Exception {
        class A {
            private String prifA;
            public String pubfA;
            @Override
            public String toString() {
                return "A [prifA=" + prifA + ", pubfA=" + pubfA + "]";
            }
        }
        class B extends A {
            public String pubfA;
            public void setPubfA(String pubfA) {
                super.pubfA = pubfA;
            }
            @Override
            public String toString() {
                return "B [pubfA=" + pubfA + ", toString()=" + super.toString() + "]";
            }
        }
        B b = new B();
        b.pubfA = "B's filed";
        b.setPubfA("A's filed");
        // B [pubfA=B's filed, toString()=A [prifA=null, pubfA=A's filed]]
        System.out.println(b);
        //
        // To get the public fields including the inherited fields from the recursively traversed parents.
        //
        //[public java.lang.String Test$1B.pubfA, public java.lang.String Test$1A.pubfA]
        System.out.println(Arrays.toString(B.class.getFields()));
        System.out.println(B.class.getFields()[1].getDeclaringClass()); //class Test$1A
        System.out.println(B.class.getField("pubfA").getDeclaringClass()); //class Test$1B
        //
        // To get the fields indirectly declared by the class regardless of its modifier.
        //
        System.out.println(Arrays.toString(B.class.getDeclaredFields()));
    }
java变参的更多相关文章
- Java 变参函数的实现
		Java的变参函数实现实际上参数是一个数组,其简单用法如下 public class variableParamTest { private static void variableParam(O ... 
- Spark案例分析
		一.需求:计算网页访问量前三名 import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /* ... 
- [转载]一个标准java程序员的进阶过程
		第一阶段:Java程序员 技术名称 内 容 说明 Java语法基础 基本语法.数组.类.继承.多态.抽象类.接口.object对象.常用类(Math\Arrarys\S ... 
- n维数组实现(可变参数表的使用)
		首先先介绍一下可变参数表需要用到的宏: 头文件:#include<cstdarg> void va_start( va_list arg_ptr, prev_param ); type v ... 
- Java的多线程机制系列:(一)总述及基础概念
		前言 这一系列多线程的文章,一方面是个人对Java现有的多线程机制的学习和记录,另一方面是希望能给不熟悉Java多线程机制.或有一定基础但理解还不够深的读者一个比较全面的介绍,旨在使读者对Java的多 ... 
- 【Go入门教程3】流程(if、goto、for、switch)和函数(多个返回值、变参、传值与传指针、defer、函数作为值/类型、Panic和Recover、main函数和init函数、import)
		这小节我们要介绍Go里面的流程控制以及函数操作. 流程控制 流程控制在编程语言中是最伟大的发明了,因为有了它,你可以通过很简单的流程描述来表达很复杂的逻辑.Go中流程控制分三大类:条件判断,循环控制和 ... 
- Java Web指导方向
		第一阶段 第二阶段 第三阶段 第四阶段 第五阶段 第六阶段 第七阶段 第一阶段:Java程序员 技术名称 内 容 说明 Java语法基础 基本语法.数组.类.继承.多态 ... 
- java effective 读书笔记
		java effective 读书笔记 []创建和销毁对象 静态工厂方法 就是“封装了底层 暴露出一个访问接口 ” 门面模式 多参数时 用构建器,就是用个内部类 再让内部类提供构造好的对象 枚举 si ... 
- Java中main方面面试题
		1.不用main方法如何定义一个类? 不行,没有main方法我们不能运行Java类. 在Java 7之前,你可以通过使用静态初始化运行Java类.但是,从Java 7开始就行不通了. 2.main() ... 
随机推荐
- Eclipse与MyEclipse修改注释字体颜色
			修改配置路劲 Window--->Preferences--->Java--->Editor--->Syntax Coloring--->Element--->Co ... 
- 【Visual Studio】“rc.exe”已退出,代码为 5 ("rc.exe" exited with code 5.)
			[解决方案]找到 rc.exe 所在目录,然后 方法1:添加该目录到 VC++ Directories --> Executable Directories中 方法2:添加到系统变量中的Path ... 
- linux下的程序调试方法汇总
			搞电子都知道,电路不是焊接出来的,是调试出来的.程序员也一定认同,程序不是写出来的,是调试出来的.那么调试工具就显得尤为重要,linux作为笔者重要的开发平台,在linux中讨论调试工具主要是为那些入 ... 
- django + gunicorn + supervisor
			在服务器上跑着一个Django项目,想用supervisor管理起来,遇到一个小问题,记录一下本来启动Django项目的命令是用的manage.py , 但是这中方法有个很神奇的坑,就是ctrl + ... 
- 【C/C++】知识点
			1.C++中的参数传递机制:值传递.指针传递.引用传递 2.C++的内部类和外部类: 一个讲得不错的博客,不过不让转载:C++内部类 3.static 可以修饰局部变量.全局变量和函数. 不可修饰类! ... 
- ios开发某个页面横不过来屏幕的时候
			某一个页面需要横屏,其他的页面任然保持竖屏需要以下关键的几个步骤: 1.修改系统代理方法的返回值 -(UIInterfaceOrientationMask)application:(UIApplica ... 
- FZU 1078 计算循环冗余码【模拟】
			计算机网络中采用循环冗余码来校验数据的正确性.其原理是:发送方计算出待发送的二进制数据的循环冗余码,并随同原数据一起发送到接收方:接收方通过重新计算接收到的数据的循环冗余码,并和收到的循环冗余码进行比 ... 
- 大型网站优化-memcache技术
			大型网站优化-memcache技术 memory+cache 内存缓存 memcache简介 memcache是一套分布式的高速缓存系统,由LiveJournal的Brad Fitzpatrick开发 ... 
- js上传Excel文件
			一.问题 需要在项目里添加一个上传excel文件的功能,因为其他同样的后台里面有上传文件的功能,第一反应就是想着直接用.了解了一下发现它是利用bootstrap的fileinput实现的,但是我怎么都 ... 
- luogu P1592 互质
			题目描述 输入两个正整数n和k,求与n互质的第k个正整数. 输入输出格式 输入格式: 仅一行,为两个正整数n(≤10^6)和k(≤10^8). 输出格式: 一个正整数,表示与n互质的第k个正整数. 输 ... 
