什么使一个变量可见(IntelliJ IDEA)

24

使用IntelliJ IDEA,如何查找变量可见性的原因?

以下是一个难以解决的示例:

  • 假设您查看类A并看到一个变量something。如果您跳转到源代码,您会发现它在trait X中定义。但是您没有直接扩展X特质。那么您扩展了什么,使得这个变量可见?如果有一个深度嵌套的层次结构,跟踪可能很困难。

是否有任何建议或解决方案?

编辑:如果您感兴趣,请为此功能投票:http://youtrack.jetbrains.com/issue/IDEA-124369


1
所以这是关于Scala集成,而不是Java? - Igor Konoplyanko
你是指CTRL+CLICK吗? - Farvardin
3
@طاهر - Ctrl+Click(或Ctrl+B)可以带您到该项的源代码。 OP 正在寻找它在文件中被引入的位置(即大多数情况下所说的“导入”)。 - Javaru
1
这将是一个非常不错的功能。如果您记录了请求,请告诉我们,以便我们可以为其投票。 - sourcedelica
1
@sourcedelica 我在JetBrains上创建了这个问题:http://youtrack.jetbrains.com/issue/IDEA-124369 - VasiliNovikov
显示剩余4条评论
7个回答

1
我认为IntelliJ IDEA没有任何“查找变量可见性”的快捷方式。
但是,您可以使用“查找用法”选项(Alt + F7)确定它。例如:
import java.nio._
object TempObj extends App {
   def func = 2
   val p = file.Paths.get("some-path")
   func
}

在“文件”上查找用法,会告诉你它来自“文件”包(在新标签页的标题中也显示完整的包名,例如:在项目文件中查找java.nio.file的用法)。 而在“func”上查找用法会告诉你它是一个方法(现在选项卡标题说:在项目和库中查找func()的用法)。

因此,现在你可以确定变量的可见性。这也适用于导入,因为它显示导入自哪个包,然后你可以查找该包的导入。


在我看来,这就像是跳转到源代码(Ctrl B)一样。你跳转之后就知道了包名。但是,你仍然不知道是什么让这个变量在你的上下文中可见。例如:trait A{def whereAmI=1}; trait B extends A; class Mystery extends B with Other with Other2 with Other3 {println(whereAmI)} 现在看着 Mystery 的源代码,我无法理解这个变量来自哪里。它是来自 B 吗?还是来自 Other?或者可能是来自扩展 A 的对象,并且我们导入了对象内容? - VasiliNovikov
实际上,“查找用途”早在之前就被提出了。不幸的是,由于所描述的原因,它并不起作用。 - VasiliNovikov
是的,你说得对,所以简短的回答是目前你找不到它。 - KarateKid

0

我知道两个几乎解决这个问题的方法。

正如你所提到的,Go-to-declaration可以解决局部变量的情况。

更一般地说,“查找用法”功能会给您一个漂亮的小窗口,按类型和文件列出变量的不同用途。从中,您可以看到它是否涉及静态导入。

虽然不是完美的,但只需花一点时间思考,这两种方法通常足以弄清楚您想要的内容。


不幸的是,“查找用法”和“转到声明”都不能完全解决问题。这些方法仍然无法涵盖“下划线”导入语句,例如“import smth._”。它们也无法帮助遍历混合树... - VasiliNovikov
在这种情况下,您面临的是IntelliJ实现的限制。很抱歉。您能做的就是使用“在路径中查找”(默认情况下为CTRL+SHIFT+F)来搜索您想要的字符串。 至少IDEA使这样的搜索快速:/ - Chris Kitching
是的,我们目前处理这种工作的方式是使用“查找所有用法”等功能。评论使我相信没有内置此类功能,因此我至少在他们的网站上创建了一个“功能请求”。 - VasiliNovikov

0

抱歉,问题不同。大致上,我想跳转到当前文件/视图中的导入/混合语句,而不是底层源代码。更详细的信息,请参见问题描述本身。 - VasiliNovikov

0

深度嵌套的层次结构听起来不太好。我理解你对此的痛苦。

当你重写val或def时,在行号旁边有一个小圆圈,显示它来自哪里,即使它来自嵌套层次结构。按下命令键悬停在vals上还会显示一个小工具提示,告诉你它的来源。

这样有帮助吗?

https://youtu.be/r3D9axSlBo8


嘿,感谢您的回答。然而,它并没有解决问题。问题是要查看什么使变量可见,而不是变量在哪里定义,就像示例中所突出显示的那样。在您的视频示例中,第18秒,希望能够看到aX可用,因为您混入了C(而C也被混入了A)。 - VasiliNovikov

0

这可能不是你希望得到的确切答案。

然而,引用你自己的话,

如果你有一个深度嵌套的层次结构,跟踪可能很困难。

你考虑过使用组合优于继承吗?也许这可以消除你正在寻找的功能需求。


0

根据我的理解,您想要查看创建您使用的对象的代码,例如 Mystery someMystery;
这给了您两个选项来填充someMystery:

  1. someMystery = ...,其中...是用于填充someMystery的代码。如果是这种情况,您应该按照该代码(如有必要,使用ctrl+B)追踪到实际创建Mystery对象的点。
  2. 使用CDI为您填充该对象实例,在这种情况下,您应该研究CDI机制,以了解对象实例是如何被填充的。

在任何情况下,我认为没有办法确定someMystery实例是否比Mystery具体的类更具体,因为它是在运行时而不是编译时决定的,所以您的下一个选择是在调试程序中运行并查看输入someMystery的对象,尽管不能保证每次都得到相同类型的对象。

PS. 我的答案完全基于我对Java主题的理解,不能确定它是否也适用于Scala。


不完全正确。我正在寻找使变量在当前代码块的编译时“可见”的内容。一个难以理解的例子是深层次的extends继承关系。你知道,最终,这是trait X的成员。但你没有直接继承X。那么它从哪里进入你的代码呢?无论如何,这在问题中已经说明了。 - VasiliNovikov
请提供您要翻译的具体内容,以便我将其翻译成中文。 - VasiliNovikov

-3
如果您希望类、字段或方法可见,就需要将它们实现为公开的。如果这是您的问题的话。

抱歉,问题是关于集成开发环境支持和代码导航的。所以,代码已经编写好了,现在您需要浏览它。 - VasiliNovikov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接