以上就是给各位分享没有传递参数或null时的Java3点参数,其中也会对varargs行为进行解释,同时本文还将给你拓展(十五)python3可变长参数(arg,*args,**kwargs)、C++
以上就是给各位分享没有传递参数或null时的Java 3点参数,其中也会对varargs行为进行解释,同时本文还将给你拓展(十五) python3 可变长参数(arg,*args,**kwargs)、C++解析命令行参数(仿C语言args)、Java Varargs 可变参数使用、Java Varargs 可变参数用法详解等相关知识,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
本文目录一览:- 没有传递参数或null时的Java 3点参数(varargs)行为(java没有引用传递 只有值传递)
- (十五) python3 可变长参数(arg,*args,**kwargs)
- C++解析命令行参数(仿C语言args)
- Java Varargs 可变参数使用
- Java Varargs 可变参数用法详解
没有传递参数或null时的Java 3点参数(varargs)行为(java没有引用传递 只有值传递)
我尝试过这个,并从JAVA中得到了奇怪的行为,有人可以帮我解释一下吗?
boolean testNull(String... string) { if(string == null) { return true; } else { System.out.println(string.getClass()); return false; }}boolean callTestNull(String s) { return testNull(s);}
然后我有测试用例:
@Test public void test_cases() { assertTrue(instance.testNull(null)); // NULL assertFalse(instance.testNull()); // NOT NULL assertFalse(instance.callTestNull(null)); // NOT NULL }
现在的问题是,如果我打电话testNull()
直接与参数null
,我会true
回来,但如果调用callTestNull()
与null
,它调用testNull()
,它告诉我该参数不为空,但空数组。
答案1
小编典典问题是,如果我直接使用参数null调用testNull(),我会回来,但如果使用null调用callTestNull()调用了testNull(),它将告诉我参数不是null,而是空数组。
是。如果使用 编译时类型 为的参数调用它String
,则编译器会知道它 不能 为String[]
,因此会将其包装在字符串数组中。所以这:
String x = null;testNull(x);
等效于:
String x = null;testNull(new String[] { x });
在这一点上,(具有误导性的)string
参数将具有非null值-相反,它将引用大小为1的数组,其唯一元素是null引用。
但是,当您null
直接在方法调用中使用文字时,它可以直接转换为String[]
,因此不执行任何包装。
从JLS第15.12.4.2节开始:
如果要调用的方法是可变Arity方法m,则它必须具有n> 0形式参数。对于某些T,m的最终形式参数必须具有T
[]类型,并且必须使用k≥0的实际参数表达式来调用m。如果m用k≠n个实际参数表达式调用,或者m用k = n个实际参数表达式调用,并且第k个参数表达式 的类型与T []分配不兼容
,则参数列表(e1,…,en-1,en,…,ek)的计算方式就像(e1,…,en-1,new | T [] | {en,…
,ek}),其中| T [] | 表示T []的擦除(第4.6节)。
(强调我的。)
我强调的一点是为什么 只 在参数的编译时类型为而String
不是null类型 时才 进行换行。
(十五) python3 可变长参数(arg,*args,**kwargs)
可变长参数(*args,**kwargs)
一、最常见的是在定义函数时,预先并不知道,函数使用者会传递多少个参数给你,所以在这个场景下使用这两个关键字。其实并不是必须写成 * args 和 **kwargs。 *(星号) 才是必须的。你也可以写成 * ar 和 **k. 而写成 * args 和 **kwargs 只是一个通俗的命名约定。分别代表的是元组和字典
def x(arg, *args, **kwargs):
print(''arg--> {}''.format(arg))
print(''args--> {} ''.format(args))
print(''kwarg--> {} ''.format(kwargs))
x(1,2,3,4,key1="value1")
#结果
# arg--> 1
# args--> (2, 3, 4)
# kwarg--> {''key1'': ''value1''}
在函数调用时,位置参数传递必须在关键字参数左边或者说前面,**kwargs 接收关键字参数,生成字典。*args 接收除第一个位置参数和关键字参数外的其它参数生成元组,根参数是什么数据类型无关。
def x(arg, *args, **kwargs):
print(''arg--> {}''.format(arg))
print(''args--> {} ''.format(args))
print(''kwarg--> {} ''.format(kwargs))
x(1,(2,3,),4,key1="value1")
#arg--> 1
#args--> ((2, 3), 4)
#kwarg--> {''key1'': ''value1''}
二、函数调用时使用 * args、**args
下面方式调用应该不难理解
def print_info(name,age,sex):
print(''name--> {}''.format(name))
print(''age--> {} ''.format(age))
print(''sex--> {} ''.format(sex))
print_info("name1",25,"男")
#name--> name1
# age--> 25
# sex--> 男
换个方式:*args,**kwargs
def print_info(name, age, sex):
print(''name--> {}''.format(name))
print(''age--> {} ''.format(age))
print(''sex--> {} ''.format(sex))
list = ["李刚", 20, "男"]
dic = {"name": "王某某", "age": 30, "sex": "女",}
print_info(*list)
# 将列表或元组前加“*”并传组函数,(注意:元素个数与位置必须对应)结果如下。
# name--> 李刚
# age--> 20
# sex--> 男
print_info(**dic)
# 同样在传入的字典前加上“**”,此时字典会被解析成key=value的形式。注意key值和个数不能大于形参,结果如下
# name--> 王某某
# age--> 30
# sex--> 女
综合一下:
print_info("小刚",age=18,**{"sex":"男"})
#
name--> 小刚
age--> 18
sex--> 男
C++解析命令行参数(仿C语言args)
说好不造轮子的,就管不住这手
#include <cstdio>
#include <string>
#include <vector>
bool ParseChar( const std::string& buf, std::size_t& pos, char& ch, bool& escape )
{
char c;
if ( pos == buf.length() )
return false;
// Get the character to parse
c = buf.at( pos++ );
if ( c == ''\\'' )
{
// Parse the escape character
if ( pos != buf.length() )
{
// Get the character to escape
c = buf.at( pos++ );
if ( c == ''\\'' || c == ''"'' )
{
ch = c;
escape = true;
}
else
{
// Does not support the character, just hold the ''\\'' character
// We need move the POS back to prepare for the character parsing
pos--;
ch = ''\\'';
escape = false;
}
}
else
{
// We can''t get the character to escape
// Just hold the ''\\'' character
ch = c;
escape = false;
}
}
else
{
// Copy the character
ch = c;
escape = false;
}
return true;
}
bool ParseToken( const std::string& buf, std::size_t& pos, std::string& token )
{
char c {};
bool escape {};
bool quote {}; // True if parsing a string
bool doing {}; // True if parsing has started
// Skip blank characters, if any
while ( pos != buf.length() )
{
c = buf.at( pos );
if ( c != '' '' && c != ''\t'' )
break;
pos++;
}
// Clean up the token
token.clear();
while ( ParseChar( buf, pos, c, escape ) )
{
if ( !doing )
{
// Parse the first character
if ( c == ''"'' && !escape )
{
// Just mark the beginning of the string, don''t copy it
quote = true;
}
else
{
// Copy the first character of the token
token.push_back( c );
}
// ''\n'' is a single character token
if ( c == ''\n'' )
return true;
// We have parsed any one character, the parsing has started
doing = true;
}
else
{
if ( quote )
{
// Copying the character of the string here
if ( c == ''"'' && !escape )
{
// Mark the ending of a string
return true;
}
else
{
// Copy the character of the string
token.push_back( c );
}
}
else
{
// Copying the character of the token here
if ( c == ''"'' && !escape )
{
// We accidentally encounter a string beginning mark before the token finished
// We need to finish the token and move the POS back to prepare for the string parsing
pos--;
return true;
}
if ( c == ''\n'' )
{
// We accidentally encounter a ''\n'' before the token finished
// We need to finish the token and move the POS back to prepare for the ''\n'' parsing
pos--;
return true;
}
if ( c == '' '' || c == ''\t'' )
{
// Mark the ending of a string
return true;
}
else
{
// Copy the character of the token
token.push_back( c );
}
}
}
}
// If no any characters are parsed, we are at the end of the buffer
// returns ''false'' to finish the parsing
return doing;
}
int main()
{
std::string cmdline = R"( connect
spawn 1
name "Billy Herrington"
flags 0xffff ""
desc "boy \\next\" door" )";
std::size_t pos {};
std::string token {};
while ( ParseToken( cmdline, pos, token ) )
{
printf_s( "[%s]\n", token == "\n" ? "\\n" : token.c_str() );
}
return 0;
}
输出如下
[connect]
[\n]
[spawn]
[1]
[\n]
[name]
[Billy Herrington]
[\n]
[flags]
[0xffff]
[]
[\n]
[desc]
[boy \next" door]
我对换行符做了点特殊处理,如果不需要可以删掉相关的判断代码
Java Varargs 可变参数使用
Java1.5 提供了一个叫varargs的新功能,就是可变长度的参数。
"Varargs"是 “variable number of arguments”的意思。有时候也被简单的称为 “variable arguments”。
定义实参个数可变的方法:只要在一个形参的"类型"与"参数名"之间加上三个连续的"."(即"...",英文里的句中省略号),就可以让它和不确定个实参相匹配。
以下实例创建了 sumvarargs() 方法来统计所有数字的值。
我们在这里的 Main 方法中添加了 new int[]{10, 12, 33, 7} 4 个参数,实际上你可以在这里持续添加不同的参数,在计算 sum 的方法中都可以根据你添加的参数来进行处理。
GIT
请参考 GitHub 上的源码代码:
https://github.com/cwiki-us/java-tutorial/blob/master/src/main/java/com/ossez/lang/tutorial/usecases/VarargsCase.java
SRC
package com.ossez.lang.tutorial.usecases;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/\*\*
\* variable arguments use case \*/public class VarargsCase {
private static final Logger logger \= LoggerFactory.getLogger(VarargsCase.class);
/\*\*
\* sumVarargs \* \* @param intArrays
\* @return
\*/
static int sumVarargs(int... intArrays) {
int sum, i;
sum = 0;
for (i = 0; i < intArrays.length; i++) {
sum += intArrays\[i\];
}
return (sum);
}
/\*\*
\* Main Function \* \* @param args
\*/
public static void main(String args\[\]) {
int sum = 0;
sum = sumVarargs(new int\[\]{10, 12, 33, 7});
logger.debug("The Sum of the arrays: {}", sum);
}
}
OUTPUT
程序运行的输出结果为:
2020/01/27 14:33:52 DEBUG [com.ossez.lang.tutorial.usecases.VarargsCase] - The Sum of the arrays: 62
Java Varargs 可变参数用法详解
Java1.5 提供了一个叫varargs的新功能,就是可变长度的参数。
"Varargs"是 “variable number of arguments”的意思。有时候也被简单的称为 “variable arguments”。
定义实参个数可变的方法:只要在一个形参的"类型"与"参数名"之间加上三个连续的"."(即"...",英文里的句中省略号),就可以让它和不确定个实参相匹配。
以下实例创建了 sumvarargs() 方法来统计所有数字的值。
我们在这里的 Main 方法中添加了 new int[]{10,12,33,7} 4 个参数,实际上你可以在这里持续添加不同的参数,在计算 sum 的方法中都可以根据你添加的参数来进行处理。
GIT
请参考 GitHub 上的源码代码:
https://github.com/cwiki-us/java-tutorial/blob/master/src/main/java/com/ossez/lang/tutorial/usecases/VarargsCase.java
SRC
package com.ossez.lang.tutorial.usecases; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * variable arguments use case */ public class VarargsCase { private static final Logger logger = LoggerFactory.getLogger(VarargsCase.class); /** * sumVarargs * * @param intArrays * @return */ static int sumVarargs(int... intArrays) { int sum,i; sum = 0; for (i = 0; i < intArrays.length; i++) { sum += intArrays[i]; } return (sum); } /** * Main Function * * @param args */ public static void main(String args[]) { int sum = 0; sum = sumVarargs(new int[]{10,7}); logger.debug("The Sum of the arrays: {}",sum); } }
OUTPUT
程序运行的输出结果为:
2020/01/27 14:33:52 DEBUG [com.ossez.lang.tutorial.usecases.VarargsCase] - The Sum of the arrays: 62
扩展学习
Java 实例 - Varargs 可变参数使用
ava1.5提供了一个叫varargs的新功能,就是可变长度的参数。
"Varargs"是"variable number of arguments"的意思。有时候也被简单的称为"variable arguments"
定义实参个数可变的方法:只要在一个形参的"类型"与"参数名"之间加上三个连续的"."(即"...",英文里的句中省略号),就可以让它和不确定个实参相匹配。
以下实例创建了 sumvarargs() 方法来统计所有数字的值:
Main.java 文件
public class Main { static int sumvarargs(int... intArrays){ int sum,i; sum=0; for(i=0; i< intArrays.length; i++) { sum += intArrays[i]; } return(sum); } public static void main(String args[]){ int sum=0; sum = sumvarargs(new int[]{10,33}); System.out.println("数字相加之和为: " + sum); } }
以上代码运行输出结果为:
数字相加之和为: 55
以上就是本次介绍的全部相关知识点,如果大家有任何补充内容可以联系我们小编。
今天关于没有传递参数或null时的Java 3点参数和varargs行为的分享就到这里,希望大家有所收获,若想了解更多关于(十五) python3 可变长参数(arg,*args,**kwargs)、C++解析命令行参数(仿C语言args)、Java Varargs 可变参数使用、Java Varargs 可变参数用法详解等相关知识,可以在本站进行查询。
本文标签: