我有一个带有4个参数的构造函数:String, Object, Object, MyEnum
。
public MyClass(String name, Object val1, Object val2, MyEnum cat) {
// find in usage = 202
this.name = name;
this.val1 = val1;
this.val2 = val2;
this.cat = cat;
}
在95%的使用案例中,最后一个参数是null
,所以我想创建另一个只接受3个参数的构造函数,并将最后一个参数设置为null。
我想到了一些想法,但最后我尝试了以下解决方案:
将最后一个参数从MyEnum
更改为Integer
(编译错误 - 无关紧要):public MyClass(String name, Object val1, Object val2, Integer cat)
- 仍然202找到用法
使用Object类型的最后一个参数添加新的构造函数:public MyClass(String name, Object val1, Object val2, Object cat)
现在第一个构造函数(Integer
)有196个用法,第二个有6个。
这正是我想要的(我有6个非null最后一个元素的调用)但是这种行为的原因是什么? Intellij是否进行了一些检查,如果输入类型为MyEnum
,则它不能作为Integer
类型传递,但是null可以传递给两者,那么为什么在第一个构造函数的情况下会减少6个结果呢? / p>
当我从Object
更改为String
时(现在我有2个带有String
和Integer
的构造函数),当我运行find usage时,它们都给我0。
感谢您解释此行为。
答案 0 :(得分:1)
如果您同时拥有guard let user = row.value else {
return
}
let phone = user.phone
let urlString = "tel://\(phone)"
let url = NSURL(string: urlString)
UIApplication.sharedApplication().openURL(url!)
和myMethod(Integer a)
,则对myMethod(Object a)
的调用将调用整数版本,因为它更具体。同样,如果您只有myMethod(null)
和myMethod(MyEnum a)
,则在传递null参数时将调用MyEnum版本。 (参见this answer关于null重载的内容,引用section 15.12.2.5 of the Java Language Specification。)根据它是Integer还是MyEnum,它的行为方式确实没有区别;两者都比Object更具体,因此选择了过载。
当您要求IntelliJ IDEA查找方法的用法时,它会使用自己的代码索引及其有关Java如何处理重载解析的知识,以查找将调用该方法的所有情况。虽然这些规则可能有点复杂(查看Java语言规范中的所有细节也会让我的眼睛受到伤害),并且可以想象有一些用例会让IDEA误解并看到与Java编译器和运行时,在这种情况下,它看起来是正确的。这是一种方便的方式来玩它并理解和测试重载解析的工作原理。
答案 1 :(得分:0)
这不是一个IntelliJ问题,而是一个java构造函数链接问题。
如果cat很可能为null,则应该有以下两个构造函数:
public MyClass(String name, Object val1, Object val2) {
this(name, val1, val2, null)
}
public MyClass(String name, Object val1, Object val2, MyEnum cat) {
this.name = name;
this.val1 = val1;
this.val2 = val2;
this.cat = cat;
}