访问修饰符在JavaFx和@FXML中的使用

huangapple go评论88阅读模式
英文:

Access modifiers in JavaFx and @FXML

问题

我对JavaFx还不熟悉,在一些教程中看到有些不同之处。在其中一个教程中,他总是在控制器类中使用private作为访问修饰符,并且这样写:

@FXML private Button button;

但另一个教程总是使用public,并且在控制器类中不包括@FXML。这两种方法似乎都能正常工作,但它们之间是否有实际区别,我应该知道吗?

英文:

I am new to JavaFx and in a few tutorials I've seen, there were some differences. In one of the tutorials, he always used private as the access modifier in the controller class and wrote it this way:

@FXML private Button button;

But the other tutorial always used public and didn't include @FXML in the controller class. Both of these seem to work fine but is there an actual difference between them that I should know?

答案1

得分: 6

FXML简介

@FXML

需要注意的是,在前面的示例中,控制器成员字段和事件处理程序方法被声明为public,以便可以被加载器设置或调用。实际上,这通常不是问题,因为控制器通常只对创建它的FXML加载器可见。然而,对于希望为控制器字段或处理程序方法选择更受限制的可见性的开发人员,可以使用javafx.fxml.FXML注解。此注解将受保护或私有的类成员标记为可由FXML访问。如果被注释的类位于一个命名模块中,则包含该类的模块必须将包含包至少openjavafx.fxml模块。

换句话说,只有在字段或方法是非public的(即受保护的、包私有的或私有的),但需要让FXML访问时,才 需要 使用@FXML注解。在FXML的上下文中,没有@FXML注解的公共字段/方法与带有该注解的非公共字段/方法之间没有区别。一般情况下,唯一的区别就是字段/方法对其他代码的可见性。

尽管如此,通常将某些内容的可见性限制在必要的范围内被认为是一种良好的做法。一个通过FXML注入的字段通常不需要是public的。事件处理程序方法和初始化方法<sup>1</sup> 也是如此。它们都是实现细节。

请注意,@FXML注解在语言层面上并没有任何特殊的作用。该注解的存在只是告诉FXMLLoader可以尝试通过反射访问该字段或方法,即使它不是public的。这对开发人员来说也是一个良好的提示,表明该字段或方法由FXML处理(例如,FXML注入的字段几乎永远不应该手动初始化或重新赋值)。


<sup>1. 无参数的initialize()方法。不是在实现Initializable时必须覆盖的那个方法,后者当然必须是public的。如果需要,建议使用无参数方法,而不是实现该接口,并像处理其他FXML注入字段一样注入位置和资源包。为什么这个接口还没有被弃用,我不知道。</sup>

英文:

From Introduction to FXML:

>### @FXML
>
>Note that, in the previous examples, the controller member fields and event handler methods were declared as public so they can be set or invoked by the loader. In practice, this is not often an issue, since a controller is generally only visible to the FXML loader that creates it. However, for developers who prefer more restricted visibility for controller fields or handler methods, the javafx.fxml.FXML annotation can be used. This annotation marks a protected or private class member as accessible to FXML. If the class being annotated is in a named module, the module containing that class must open the containing package to at least the javafx.fxml module.

In other words, the @FXML annotation is only required if the field or method is non-public (i.e. is protected, package-private, or private) yet needs to be accessible to FXML. Within the context of FXML, there is no difference between a public field/method with no (or even with an) @FXML annotation and a non-public field/method with said annotation. The only difference in general is the visibility of the field/method to other code.

That said, it's typically considered good practice to only make something as visible as it needs to be. An FXML-injected field normally has no reason to be public. Neither do event-handler methods nor does the initialize method<sup>1</sup>. They're all implementation details.

Note the @FXML annotation doesn't do anything special on a language level. The presence of the annotation simply tells the FXMLLoader it's okay to try and reflectively access the field or method even though it's not public. It's also a good hint to the developer that the field or method is handled by FXML (for instance, FXML-injected fields should virtually never be manually initialized or reassigned).


<sup>1. The no-argument initialize() method. Not the one you have to override when implementing Initializable, which of course must be public. Note it's recommended to use the no-argument method instead of implementing that interface, injecting the location and resource bundle the same as other FXML-injected fields if needed. Why the interface hasn't been deprecated yet, I don't know.</sup>

huangapple
  • 本文由 发表于 2020年4月5日 23:11:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/61044743.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定