Java最佳实践 - 在类变量之前声明构造函数是一件坏事吗?

时间:2012-04-22 01:18:18

标签: java coding-style

我正在从一位同事(另一位学生)那里进行Java代码的“静态”代码演练

对我来说,这没有意义;从上到下阅读这些“组件”对象在声明之前进行实例化(稍后在构造函数中使用)。但是,代码很乐意编译并运行。这是不好的做法吗?

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

7 个答案:

答案 0 :(得分:37)

Sun Microsystems(现已由Oracle接管)于1998年发布了Java Coding Style Guide,其中他们向一个特定组织推荐了类声明:

  1. 静态变量字段声明
  2. 实例变量字段声明
  3. 静态初始化程序
  4. 静态成员内部类声明[*]
  5. 静态方法声明
  6. 实例初始化程序
  7. 实例构造函数声明
  8. 实例成员内部类声明[*]
  9. 实例方法声明
  10. 请注意,这会将数据声明放在文件的顶部。 (earlier Sun publication from 1997没有涵盖上面列表中的所有内容。)唯一重要的排序是在静态字段和实例字段中,然后仅当字段包含引用其他字段的初始化程序时。在初始化之前,您不能在初始化程序中使用字段。类似地,初始化程序(项目3或6)不能对字段进行前向引用,除非作为赋值的目标。 (有关此类前向引用的更多信息,请参阅Java Language Specification, Section 8.3.3。)据我所知,该命令无关紧要。

    [*]上述清单中的术语(从1998年指南逐字逐句)对于第4项和第8项已经过时。具体来说,来自Java tutorial on nested classes

      

    术语:嵌套类分为两类:静态和非静态。声明为static的嵌套类称为静态嵌套类。非静态嵌套类称为内部类

    在现代用法中,没有“静态成员内部类”这样的东西。

答案 1 :(得分:9)

对此没有真正的共识。大多数人会在类实现的顶部声明类变量,然后是方法,但这不是必需的。像Code Complete这样的一些书建议将变量尽可能接近地宣布为首次使用。这有助于将变量的范围减小到最小。

答案 2 :(得分:7)

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() {}
    }

每组中的顺序应为

  1. 公共
  2. 受保护
  3. 包级别(无访问修饰符)
  4. 私人

答案 3 :(得分:5)

在宣布之前,不会对它们进行实例化。初始化的顺序在Java中是固定的,并且在您放置声明和构造函数的代码中 where 并不重要。

至于惯例,它实际上取决于你感到满意。虽然事实上的惯例是首先声明文件,然后是构造函数,但只要不违反您的性质或公司规定,您的方法就像其他任何方法一样有效。

此外,你的代码中存在更多危险的东西,使其不易读取,例如单字母变量或大量使用不太常见的结构(例如复杂条件的三元运算符)。组织代码是一个较小的问题,因为任何体面的IDE都可以通过你放在那里的任何设置重新组织代码。

答案 4 :(得分:2)

声明类(方法,属性)成员的 order 是无关紧要的。按照惯例,首先声明所有属性和常量,然后是方法。

例如,在您的代码中:可以在构造函数中初始化属性,然后然后声明属性,因为在编译类时,将考虑所有属性声明,以及稍后,当构造函数实际上是调用时,将找到属性。请注意,构造函数中的属性在编译时未被访问,这就是它们不会产生错误的原因;它们只能在运行时访问。

答案 5 :(得分:2)

这与普通约定相反,并且(因此)它使得代码对于期望遵循常规约定的人来说更不可读...即大多数Java程序员。

另一方面,如果代码一致地执行此操作,并遵循约定的本地编码约定,那么读者将习惯它。

问题的回答“这是不好的做法吗?”是因为它取决于您商定的编码约定,以及它对此的说法。

但是元回答是在没有商定的编码约定的情况下进行代码审查是一个非常糟糕的主意。如果没有编码约定,则没有审查代码样式的客观依据。你最终可能会得到一个糟糕的结果。

答案 6 :(得分:2)

Main Java Language specification define in sections 8.1.1, 8.3.1 and 8.4.3 following flow which we have to using:

  1. public
  2. protected
  3. private
  4. abstract
  5. static
  6. final
  7. transient
  8. volatile
  9. synchronized
  10. native
  11. strictfp

This order we have to use when we are writing code in Java ;)

Link to the Java Language Specification