当我点击查找用法时,Intellij如何选择构造函数?

时间:2016-07-19 13:44:35

标签: intellij-idea

我有一个带有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。

我想到了一些想法,但最后我尝试了以下解决方案:

  1. 将最后一个参数从MyEnum更改为Integer(编译错误 - 无关紧要):public MyClass(String name, Object val1, Object val2, Integer cat) - 仍然202找到用法

  2. 使用Object类型的最后一个参数添加新的构造函数:public MyClass(String name, Object val1, Object val2, Object cat)现在第一个构造函数(Integer)有196个用法,第二个有6个。

  3. 这正是我想要的(我有6个非null最后一个元素的调用)但是这种行为的原因是什么? Intellij是否进行了一些检查,如果输入类型为MyEnum,则它不能作为Integer类型传递,但是null可以传递给两者,那么为什么在第一个构造函数的情况下会减少6个结果呢? / p>

    当我从Object更改为String时(现在我有2个带有StringInteger的构造函数),当我运行find usage时,它们都给我0。

    感谢您解释此行为。

2 个答案:

答案 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;
}