【问题标题】:Java :Setter Getter and constructorJava :Setter Getter 和构造函数
【发布时间】:2013-07-30 08:06:06
【问题描述】:

我对 getter/setter 和构造函数的使用有点困惑(请参阅下面的代码示例)

    public class ExampleClass {

        private int value = 0; 

        public ExampleClass () {
            value = 0; 
        }

        public ExampleClass (int i) {
            this.value = i;
        }

        public int getValue() {
            return value; 
        }

        public void setValue(int val) {
            this.value = val; 
        }

        public static void main(String[] args) {     
            ExampleClass example = new ExampleClass (20);
            example.setValue(20); 
            //Both lines above do same thing - why use constructor? 
            System.out.println(example.getvalue());
        }
   }

我所知道的是,我们需要 getter/setter 以确保安全,并且它们也可以用于以后更改或编辑值

我的问题是,如果构造函数是初始化点并且始终存在默认构造函数,为什么要使用带参数的构造函数而不是 getter/setter 来初始化值?。不会使用 getter 和 setter 提供安全性以及能够在任何阶段轻松更改值。请为我澄清这一点。

【问题讨论】:

  • 构造函数用于在创建对象时初始化值。例如 int 的默认值为 0。如果要创建 int 参数值不为 0 的实例,可以使用构造函数。
  • 如果你使用setter,它们实际上是方法,所以如果你有多个setter,那么最好使用构造函数。如果您为多个变量调用 setter 将比将它们都传递给一个构造函数并仅在一种方法中设置它们要慢。在这种情况下,构造函数比多个 setter 更快,显然它们都有多个优点,决定权在你。

标签: java class constructor setter getter


【解决方案1】:

为了回答这个问题,我说通过编写 getter/setter,我们创建一个规定,以在将来添加任何验证方法,目前,没有验证,但如果将来出现任何问题,我们只需在其中添加验证逻辑二传手。

我们也可以在构造函数中编写逻辑/验证,但这不是一个好习惯。构造函数应仅用于初始化对象的状态/字段。您应该将其他事情的责任委托给其他方法。 请注意,构造函数仅被调用一次,即每当您创建一个新对象时,如果输入足够大,您可能会在构造函数中引发异常。 这是您不应该使用构造函数来包含“业务逻辑”的几个原因之一。

【讨论】:

    【解决方案2】:

    这完全取决于您的编码风格。但是 IMO,我会使用参数化构造函数:

    1. 初始化那些不应更改的值。 (如个人对象的用户名参数)

    2. 初始化这些值,如果不设置,对象将处于无效状态。

    说,你正在向一个方法发送登录参数。您可以通过这些方式使用

    Login obj = new Login();
    obj.setUsername("user");
    obj.setPassword("pw")// what if someone commented this out, or you forget to call it
    
    
    and otherway,
    Login obj = new Login("user", "pw");
    

    虽然您可以在第一种情况下设置用户名后发送登录对象,但在接收端将无效。但是第二种方法不太容易出现错误,因此需要传递所有必需的参数。

    【讨论】:

    • 很好的解释,谢谢。
    【解决方案3】:

    首先,两种方法:Constructor 和 Setter 都是更改对象属性的安全方法。期望类作者公开或不安全的方式来修改实例。

    1. 如果您还没有编写默认构造函数,则始终提供:

      // Example of a Class with a Default Constructor 
      public class GetSet {
      
          private String value;
      
          public String getValue() {
              return value;
          }
          public void setValue(String value) {
              this.value = value;
          }
      
      
          public static void main(String[] args) {
              // Theres a implicit Default Constructor here
              // Its ok to do that
              // GetSet obj = new GetSet();
              GetSet obj = new GetSet();
          }
      
      }
      
      
      // Example of a Class without a Default Constructor 
      public class GetSet2 {
      
          public GetSet2(String value) {
              this.value = value;
          }
      
          private String value;
      
          public String getValue() {
              return value;
          }
          public void setValue(String value) {
              this.value = value;
          }
      
          public static void main(String[] args) {
              // GetSet2 obj = new GetSet2(); // compile time error
              // Default constructor is not provided, since u wrote one
          }
      
      }
      


    2.关于哪个更好:使用构造函数或通过setter,这取决于你想要什么。如果您只修改现有对象的属性,您可以使用 setter,或者对于完全填充的对象,您可能更喜欢构造函数。

        // Example of modifing an obj via Setter and Constructor
        public class GetSet3 {
    
            public GetSet3(String value1, String value2, String value3, String value4) {
                this.value1 = value1;
                this.value2 = value2;
                this.value3 = value3;
                this.value4 = value4;
            }
    
            private String value1;
            private String value2;
            private String value3;
            private String value4;
    
    
            // ... Getters and Setters
    
    
    
            public static void main(String[] args) {
    
                // Its easier to this
                GetSet3 obj;
    
                obj= new GetSet3("j", "a", "v", "a");
    
                // instead that
                // its also easy to forget or do something wrong
                // when u have a lot of attributes to set
                obj.setValue1("j");
                obj.setValue2("a");
                obj.setValue3("v");
                obj.setValue4("a");
    
            }
        }
    

    【讨论】:

      【解决方案4】:

      因为当您将值设置为构造函数中的参数时,您会使用更少、更优雅且可读性更好的代码来编写它。此外,有时某些字段对于对象来说是必不可少的,因此参数构造函数会阻止用户创建省略对象功能所需字段的对象。一个人虽然没有“义务”调用设置者。

      【讨论】:

        【解决方案5】:

        默认构造函数始终存在

        其实它并不总是在那里。默认构造函数是编译器提供的构造函数(当然它是无参数构造函数)仅当类中没有定义其他构造函数时

        为什么我们使用带参数的构造函数来初始化值而不是 set get

        因为可能存在这样一个条件,即只有在初始化本身时提供了所有值并且没有默认值时,才能始终创建对象。所以必须提供所有值,否则代码将无法编译。

        考虑这个Book

        public class Book {
        
            private String title;
            private String author;
        
            public Book(String title, String author){
                this.title = title;
                this.author = author;
            }
             //getters and setters here 
        }
        

        考虑这样一种情况,即只有具有titleauthor 的书才能创建。

        • 您不能执行new Book(),因为没有无参数构造函数,并且编译器不会提供一个,因为已经定义了一个构造函数。
        • 您也不能这样做new Book(),因为我们的条件不符合,因为每本书都需要标题和作者。

        这是参数化构造函数有用的条件。

        【讨论】:

          【解决方案6】:

          带参数的构造函数使您可以完全构造对象。如果要使用默认值,则必须确保使用 setter 设置字段。在设置某些属性期间,假设抛出异常,现在您有一个不可用的对象。在某些情况下,setter 不会被暴露,而是 getter。在这些情况下,使用带参数的构造函数或命名构造函数是正确的选择。简而言之,getter 和 setter 确实有它们自己的重要性,而不是初始化对象。

          Why use getters and setters?

          【讨论】:

            【解决方案7】:

            有时,当创建一个类的新对象时,必须提供一些值。例如,当连接到数据库并创建 Connection 类对象时,您必须提供一个连接字符串,以便它知道您连接到什么。在不指定目标数据库的情况下创建新连接将毫无用处,对吧?

            另外,看看这个

            Foo foo=new Foo(1,2,3,4,5,6,7);
            

            还有这个

            Foo foo=new Foo();
            foo.setP1(1);
            foo.setP2(2);
            foo.setP3(3);
            foo.setP4(4);
            foo.setP5(5);
            foo.setP6(6);
            foo.setP7(7);
            

            第一个看起来更好,对吧?

            【讨论】:

              【解决方案8】:

              有时您不需要在创建时将所有字段设置为特定值。例如,当你制作一个数组时。此外,如前所述,使用 getter 会更安全——您无法获取空指针。

              当您定义了带参数的构造函数时,请记住编写默认构造函数。或者一定不要使用它。

              【讨论】:

                【解决方案9】:

                我的问题是,如果构造函数是初始化点并且 默认构造函数总是在那里,所以为什么我们使用构造函数 参数来初始化值而不是 set get。

                如果你考虑一个对象转换到不同的状态,那么有一个参数化的构造函数以及 setter 和 getter 是有意义的。让我试着放一个真实的场景:考虑一个 Employee 类,一个新员工加入,你不知道很多细节但很少,你创建了 Employee 对象,其属性的默认值和基值。您需要在系统中注册员工,因此您使用了参数化构造函数。获得有关员工的更多详细信息后,您可以使用 getter 和 setter 来更新属性。

                【讨论】:

                  【解决方案10】:

                  通过构造函数初始化对象变量以避免空指针更容易和更安全。

                  如果您在没有先初始化变量的情况下实例化您的对象,并且对其中一个空变量执行 get 操作,您可能会在运行时遇到空指针异常,因为您忘记手动设置它的值。

                  另一方面,如果您始终在默认构造函数中初始化对象变量,则在运行时出现空指针异常的风险会大大降低,因为除非您通过 setter(不推荐)。

                  【讨论】:

                  • 所以编译器不会为空指针给出异常/错误?如果它给出,那么我们可以初始化它我认为这很容易解决,对吗?
                  【解决方案11】:

                  只是为了让它更容易。与创建对象和使用 setter 相比,使用构造函数所需的代码更少。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 2017-03-05
                    • 2011-07-10
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2019-06-25
                    相关资源
                    最近更新 更多