如题:
private boolean IsStringValid(String _str)
{ return (_str == null || _str.isEmpty()); }
private boolean IsStringValid(String... _strs)
{
for (String str : _strs) {
if (!IsStringValid(str))
return false;
}
return true;
}
在使用时,可变参数的构造,是不是要在内部先做一个数组,再进行元素赋值,最后把数组传递给可变参数?
请高手说明一下这个实现的原理,多谢了哈~~~
------解决思路----------------------
可变参数是语法糖,本身就是个数组。isStringValid(String[])这种调用是合理的。
可变参数在方法重载中具有最低的优先级。 isStringValid(String)这种调用会调用到第一个方法。
------解决思路----------------------
进下面的帖子去看看吧,对于可变参数的原理及注意问题,我在帖子里写了一些。如有不明白的,欢迎追问!

帖子连接
------解决思路----------------------
这个不会有性能问题的,如果真要鸡蛋里挑骨头的话,就是比实际数据大小会多出约3个“字宽”大小,在32位虚拟机中,1个字宽是32位(4字节),64位虚拟机则1字宽为64位(6字节)
在JAVA中数组底层实现就是一个类。只不是该类是直接由JVM底层实现并创建的(JVM指令newarray)。通过反射可以测试出该类没有任何成员属性(为何可以用.length,其实.length不是属性,编译后会被转换成一个jvm指令arraylength),所以数组占用大小只有“对象头”会占用一些。
对象头占用大小为3个字宽(非数组对象占2个字宽),包含3部分内容:
1、Mark Word(存储对象的hashCode或锁信息) 32bit/64bit
2、Class Metadata Adderss(存储对象类型数据的指针) 32bit/64bit
3、Array length(数组的长度) 32bit
想了解详细内容你可以去java官网阅读下 java Object model的相关资料!
------解决思路----------------------
进下面的帖子去看看吧,对于可变参数的原理及注意问题,我在帖子里写了一些。如有不明白的,欢迎追问!
帖子连接
谢谢了哈,帖子很清晰,特别好~~~
另外,想冒昧问一下,在底层的时候,总会new一个数组,对吧?这样的话,会不会造成性能损失?
这个不会有性能问题的,如果真要鸡蛋里挑骨头的话,就是比实际数据大小会多出约3个“字宽”大小,在32位虚拟机中,1个字宽是32位(4字节),64位虚拟机则1字宽为64位(6字节)
在JAVA中数组底层实现就是一个类。只不是该类是直接由JVM底层实现并创建的(JVM指令newarray)。通过反射可以测试出该类没有任何成员属性(为何可以用.length,其实.length不是属性,编译后会被转换成一个jvm指令arraylength),所以数组占用大小只有“对象头”会占用一些。
对象头占用大小为3个字宽(非数组对象占2个字宽),包含3部分内容:
1、Mark Word(存储对象的hashCode或锁信息) 32bit/64bit
2、Class Metadata Adderss(存储对象类型数据的指针) 32bit/64bit
3、Array length(数组的长度) 32bit
想了解详细内容你可以去java官网阅读下 java Object model的相关资料!
非常感谢哈,你这个回复很能说明问题。
我刚才写了个程序测了一下,win7 x64, 8 CPU, 16G RAM,效果差别比较大,请帮忙讲解一下,多谢了哈~~
运行结果:
TryIt1 ............
5
TryIt2 ............
586
public class Test01 {
private static boolean TryIt1(String str1, String str2, String str3, String str4)
{
if (str1 != null && str2 != null && str3 != null && str4 != null)
return true;
return false;
}
private static boolean TryIt2(String ... args)
{
for (String str : args)
{
if (str == null)
return false;
}
return true;
}
private static void CallTryIt1()
{
String str1 = "A";
String str2 = "B";
String str3 = "C";
String str4 = "D";
int iLoopCount = 9999;
System.out.println("TryIt1 ............");
long lTimeBegin = System.currentTimeMillis();
for (int i = 0; i < iLoopCount; ++i)
for (int j = 0; j < iLoopCount; ++j)
TryIt1(str1, str2, str3, str4);
long lTimeEnd = System.currentTimeMillis();
System.out.println(lTimeEnd-lTimeBegin);
}
private static void CallTryIt2()
{
String str1 = "A";
String str2 = "B";
String str3 = "C";
String str4 = "D";
int iLoopCount = 9999;
System.out.println("TryIt2 ............");
long lTimeBegin = System.currentTimeMillis();
for (int i = 0; i < iLoopCount; ++i)
for (int j = 0; j < iLoopCount; ++j)
TryIt2(str1, str2, str3, str4);
long lTimeEnd = System.currentTimeMillis();
System.out.println(lTimeEnd-lTimeBegin);
}
public static void main(String[] args) {
CallTryIt1();
CallTryIt2();
}
}
sorry,忘记说明了,在JDK7之前的版本,可变参数确实会有性能的问题,耗时主要发生在频繁创建和销毁数据对象,在JDK7版本开始,对JVM做了一些优化,使用恰当的话,二者性能差不多。以你当前的例子。在TryIt2方法中,应该调整下,修改为:
if (args[0] != null && args[1] != null && args[2] != null && args[3] != null)
return true;
return false;
因为你之前用的是for循环加if判断,效率上本身就低一些,测试次数增大了,二者区别就明显了。修改为上述代码后,在JDK7前随着测试量增大,性能会明显看出来。但在JDK7版本,就不会有这个问题。