Java 最佳实践 - 在类变量之前声明构造函数是一件坏事吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10264447/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java best practice - Is declaring the constructor before the class variables a bad thing?
提问by mitch_au
I'm undertaking a 'static' code walkthrough of Java code from a colleague (another student)
我正在从同事(另一个学生)那里进行 Java 代码的“静态”代码演练
To me, this doesn't make sense; reading from top to bottom these 'component' objects are instantiated (and later used in the constructor) before they are declared. But, the code happily compiles and runs. Is this bad practice?
对我来说,这没有意义;从上到下读取这些“组件”对象在它们被声明之前被实例化(然后在构造函数中使用)。但是,代码愉快地编译和运行。这是不好的做法吗?
Public Class theObject {
private static final long aVariable = 123123123123123;
public theObject(...){
componentOne = new Component(...);
componentTwo = new Component(...);
...
...
componentOne.doSomething(...);
}
private Component componentOne;
private Component componentTwo;
}
回答by Ted Hopp
Sun Microsystems (now taken over by Oracle) published its Java Coding Style Guidein 1998, in which they recommended a particular organization to class declarations:
Sun Microsystems(现在被 Oracle 接管)在 1998 年发布了它的Java Coding Style Guide,他们在其中推荐了一个特定的组织来进行类声明:
- Static variable field declarations
- Instance variable field declarations
- Static initializer
- Static member inner class declarations [*]
- Static method declarations
- Instance initializer
- Instance constructor declarations
- Instance member inner class declarations [*]
- Instance method declarations
- 静态变量字段声明
- 实例变量字段声明
- 静态初始化器
- 静态成员内部类声明 [*]
- 静态方法声明
- 实例初始化器
- 实例构造函数声明
- 实例成员内部类声明 [*]
- 实例方法声明
Note that this puts the data declarations at the top of the file. (An earlier Sun publication from 1997did not cover everything in the above list.) The only important ordering is within the static fields and within the instance fields, and then only if the fields contain initializers that refer to other fields. You cannot use a field in an initializer before it itself has been initialized. Similarly, an initializer (item 3 or 6) cannot make a forward reference to a field, except as the target of an assignment. (See the Java Language Specification, Section 8.3.3, for more information on such forward references.) As far as I know, nothing else about the order matters.
请注意,这会将数据声明放在文件的顶部。(1997 年较早的 Sun 出版物并未涵盖上述列表中的所有内容。)唯一重要的排序是在静态字段内和在实例字段内,然后仅当这些字段包含引用其他字段的初始化程序时。在初始化器本身被初始化之前,你不能在初始化器中使用它。类似地,初始化器(第 3 项或第 6 项)不能对字段进行前向引用,除非作为赋值的目标。(有关此类前向引用的更多信息,请参阅Java 语言规范的第 8.3.3 节。)据我所知,顺序无关紧要。
[*] The terminology in the above list (which is verbatim from the 1998 guide) is out of date with regards to items 4 and 8. Specifically, from the Java tutorial on nested classes:
[*] 上面列表中的术语(来自 1998 年指南的逐字逐句)对于第 4 项和第 8 项已经过时了。具体来说,来自嵌套类的Java 教程:
Terminology:Nested classes are divided into two categories: static and non-static. Nested classes that are declared
static
are called static nested classes. Non-static nested classes are called inner classes.
术语:嵌套类分为两类:静态和非静态。声明
static
的嵌套类称为静态嵌套类。非静态嵌套类称为内部类。
In modern usage, there is no such thing as a "static member inner class".
在现代用法中,没有“静态成员内部类”这样的东西。
回答by Chris911
There's no real consensus about this. Most people will declare class variables at the top of the class implementation followed by the methods but that's not a requirement. Some books like Code Complete suggest declaring variables as close as possible as their first use. This helps reducing the scope of a variable to a minimum.
对此没有真正的共识。大多数人会在类实现的顶部声明类变量,然后是方法,但这不是必需的。一些像 Code Complete 这样的书建议在第一次使用时尽可能接近地声明变量。这有助于将变量的范围缩小到最小。
回答by Vidura Mudalige
The general declaration order in java, (Reference: Java Coding Style Guide)
java中的一般声明顺序,(参考:Java Coding Style Guide)
public class DeclarationOrder {
// Class (static) variables
public static int publicClassVariable;
protected static int protectedClassVariable;
static int defaultClassVariable;
private static int privateClassVariable;
// Instance variables
public int publicInstanceVariable;
protected int protectedInstanceVariable;
int defaultInstanceVariable;
private int privateInstanceVariable;
// Constructors
public DeclarationOrder() {
// Public Constructor
}
protected DeclarationOrder(int var) {
// Protected Constructor
}
DeclarationOrder(String var) {
// Default Constructor
}
private DeclarationOrder(Double var) {
// private Constructor
}
// Class (static) Methods
public static void publicClassMethod(){}
protected static void protectedStaticMethod(){}
static void defaultStaticMethod() {}
private static void privateStaticMethod(){}
// Instance Methods
public void publicInstaceMethod() {}
protected void protectedInstanceMethod() {}
void defaultInstanceMethod() {}
private void privateInstanceMethod() {}
}
The order within each set should be,
每个集合内的顺序应该是,
- Public
- Protected
- Package level (no access modifier)
- Private
- 上市
- 受保护
- 包级别(无访问修饰符)
- 私人的
回答by Jakub Zaverka
No they are not instantiated before thay are declared. The order of initialisation is fixed in Java and it doesn't matter wherein the code you put your declarations and constructors.
不,它们在声明之前不会被实例化。初始化的顺序是固定的Java和它没有关系,其中的代码,你把你的声明和构造函数。
As for convention, it really depends on what you are comfortable with. While the truth is the convention is to declare fileds first and then the constructors, your approach is as valid as any other, as long as it is not against your nature or company regulations.
至于约定,这实际上取决于您对什么感到满意。虽然事实是惯例是先声明字段,然后是构造函数,但您的方法与其他方法一样有效,只要它不违反您的性质或公司规定。
Moreover, there is much more dangerous stuff to put in your code that makes it less readable, such as one-letter variables or extensive use of less common structures (ternary operator for complex conditions, for example). Organizing the code is one of the lesser concerns, as any decent IDE can reorganize the code by whatever settings you put there.
此外,在您的代码中放入更危险的东西会降低其可读性,例如单字母变量或广泛使用不太常见的结构(例如,用于复杂条件的三元运算符)。组织代码是较少关注的问题之一,因为任何体面的 IDE 都可以通过您放置的任何设置重新组织代码。
回答by Stephen C
It is contrary to normal conventions, and (as such) it makes the code less readable for people who expect the normal conventions to be followed ... i.e. most Java programmers.
它与常规约定相反,并且(因此)它使希望遵循常规约定的人的代码可读性降低……即大多数 Java 程序员。
On the other hand, if the code does this consistently, and it follows an agreed local coding convention, then readers will get used to it.
另一方面,如果代码始终如一地执行此操作,并且遵循商定的本地编码约定,那么读者就会习惯它。
So the answer to the question "Is this bad practice?"is that it depends on your agreed coding convention, and what it says about this.
所以这个问题的答案是“这是不好的做法吗?” 是它取决于您同意的编码约定,以及它对此的说明。
But the meta-answer is that doing a code review without an agreed coding convention is a really bad idea. If there is no coding convention, there is no objective basis for reviewing code style. You are liable to end up with a bad outcome.
但是元答案是在没有商定的编码约定的情况下进行代码是一个非常糟糕的主意。如果没有编码约定,就没有代码风格的客观依据。你很可能会得到一个糟糕的结果。
回答by óscar López
The orderin which the members of a class (methods, attributes) are declared is irrelevant. By convention it's common to first declare all attributes and constants, then the methods.
的顺序,其中一个类(方法,属性)的成员声明是无关紧要的。按照惯例,通常首先声明所有属性和常量,然后是方法。
For example, in your code: it's possible to initialize the attributes in the constructor and thendeclare the attributes, simply because when a class is compiled all attribute declarations will be taken into account, and later, when the constructor is actually called, the attributes will be found. Notice that the attributes in the constructor are not being accessed at compile time, that's why they don't produce an error; they only get accessed at run time.
例如,在您的代码中:可以在构造函数中初始化属性然后声明属性,这仅仅是因为在编译类时将考虑所有属性声明,稍后,当实际调用构造函数时,属性会被发现。请注意,在编译时不会访问构造函数中的属性,这就是它们不会产生错误的原因;它们只能在运行时访问。
回答by Dmytro Melnychuk
Main Java Language specification define in sections 8.1.1, 8.3.1 and 8.4.3 following flow which we have to using:
主要 Java 语言规范在第 8.1.1、8.3.1 和 8.4.3 节中定义了我们必须使用的以下流程:
- public
- protected
- private
- abstract
- static
- final
- transient
- volatile
- synchronized
- native
- strictfp
- 上市
- 受保护
- 私人的
- 抽象的
- 静止的
- 最后
- 短暂的
- 易挥发的
- 同步的
- 本国的
- 严格的fp
This order we have to use when we are writing code in Java ;)
我们在用 Java 编写代码时必须使用这个顺序;)