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个正整数. 输 ...