【问题标题】:correct way of initializing variables初始化变量的正确方法
【发布时间】:2010-04-26 16:17:58
【问题描述】:

好吧,这只是在黑暗中的一个镜头,但它可能是我得到的大多数错误的原因。

当你初始化某些东西时。让我们说一个小摇摆程序。会这样吗

variables here
{
  private Jlist contactList;
  String [] contactArray;
  ArrayList <String> contactArrayList;
  ResultSet namesList


// constructor here

public whatever()
{
    GridLayout aGrid = new GridLayout(2,2,10,10);

    contact1 =  new String();
    contact2 =  new String();
    contact3 =  new String();

    contactArrayList = new ArrayList<String>();

// is something supposed too go in the () of this JList?
   contactList = new JList();

   contactArray = new String[5];

   from1 =new JLabel ("From: " + contactArray[1]);



gridlayout.add(components)// theres too many components to write onto SO.

}


// methods here

public void fillContactsGui()
{
    createConnection();
ArrayList<String> contactsArrayList = new ArrayList<String>();

    while (namesList.next())
    {
        contactArrayList.add(namesList.getString(1));
        ContactArray[1] = namesList[1];
    }
}

我知道这可能是一个巨大的初学者问题,但这也是我使用的代码。我也毫无意义地初始化了三四次,因为我不确定它们在哪里。任何人都可以对此有所了解吗?

附言对不起,凌乱的示例代码。我已经尽力了。


好吧,这里再清楚一点。

我要问的是代码的总体布局。

我的代码是这样格式化的。

变量; 构造函数; 方法;

我说它应该看起来像这样对吗

 public class test
{
  int i;

  public test()
  {
    i = 0;
 }

  public void addi()
  {
   i = i +1;
  }
}

不是这样的

public class test
{
  int i = 0;

  public test()
  {
   int i = 0;
  }


  public void addi()
  {
    int i = i +1;
  }
}

我试图找出初始化变量的正确方法。因为我每次使用它们时都会定义它们

【问题讨论】:

  • 你的问题对我来说不是很清楚。您收到的错误消息是什么?
  • 这是你的代码还是只是一个sn-p?很难看到您的代码实际在做什么,因此我们很难为您提供帮助。
  • 您是在问“会这样吗”,而不是特定的其他方式,还是一般而言?如果只是一般来说,这是没有更多信息就无法回答的问题之一;没有一个正确的方法来初始化每个程序。
  • 抱歉不清楚。但我的真实代码非常糟糕。基本上,我在我的构造函数、变量部分(顶部)和我的方法中初始化了东西。我不确定我应该在哪里初始化它们。有更清楚的吗?
  • @Lord Torgamus.. 愿意解释一下吗?看到我认为所有的东西都以同样的方式初始化。该代码应该也比我拥有的代码清晰得多。抱歉,如果它令人困惑

标签: java swing initialization constructor


【解决方案1】:

变量可以出于不同的原因在不同的位置初始化。例如,在您的示例代码中,您总是将您的联系人列表初始化为一个新的 JList。这可以在“这里的变量”部分以private JList contactList = new JList() 完成。

您的contactArrayList 看起来通常基于传递给构造函数的参数,因此应在构造函数中将项目添加到其中。如果您要采用这种方法,则应将contactArrayList 声明为final。这将强制所有构造函数初始化列表。 (如果您不想将其声明为 final,则需要在声明时以与处理 contactList 相同的方式对其进行初始化。)

有时,在构造类的实例之前,不能(或不应该)初始化字段。在这些情况下,您必须非常小心地访问和使用该字段,以确保它不会在未初始化状态下使用。

【讨论】:

    【解决方案2】:

    您通常应该尽快初始化变量——只要初始值已知。而不是

    ArrayList<String> contactArrayList;
    

    考虑一下

    static final int INITIAL_LIST_SIZE = 100;
    List<String> contactArrayList = new ArrayList<String>(INITIAL_LIST_SIZE);
    

    这里是类变量、实例变量或数组组件的default values 列表。

    附录:通常不赞成重复默认初始化。在您后面的示例中,默认初始化将 i 设置为零。

    勘误:请注意在 test 构造函数中关于 int i = 0 的更正注释,该构造函数隐藏了字段 i

    public class test {
    
        int i = 0; // superfluous, "int i;" is enough 
    
        public test() {
            int i = 0; // hides field i
        }
    
        public void addi() {
            int i = i + 1; // hides field i; won't increment field i
        }
    }
    

    【讨论】:

    • @trashgod 所以越早越好。好的,我可以理解。 id 在顶部定义我的变量并对其进行初始化。但是可以说我不知道​​在方法之前会发生什么。我该怎么写。我会在顶部创建一个变量,将其排除在构造函数之外并将其放入方法中吗?一个例子会很棒。
    • 常量 INITIAL_LIST_SIZE 只是一个最佳估计值。如果没有更好的猜测,您将依赖默认构造函数的值 10,new ArrayList&lt;String&gt;()java.sun.com/javase/6/docs/api/java/util/ArrayList.html
    • "我将如何编写它。我会在顶部创建一个变量,将它放在构造函数之外并将其放入方法中吗?"确切地。然后你只需要小心在变量初始化之前不要尝试访问它。正如约翰 D 所说,这有点不寻常。通常,对象中的所有变量都将在构造函数中初始化,或者只是内联在“变量部分”中,即使它们被初始化为空列表或空映射。
    • @OVERTONE:抱歉评论不正确;请参阅上面的勘误表。
    【解决方案3】:

    不初始化的唯一问题是你让自己对空指针异常保持开放。理想情况下,您应该在构造函数中初始化您需要的所有内容,这样您就可以确保所有其他方法都可以使用。另一种方法是在调用方法之前检查事物是否为空(例如if (list != null &amp;&amp; list.size() &gt; 0)

    【讨论】:

      【解决方案4】:

      本教程在Object Initialization in Java 上回答了您的许多问题。

      您将了解实例变量根据其类型、何时使用静态初始化器、何时使用构造器、与继承相关的初始化等初始化为默认值。

      这里有一些其他有价值的资源:

      【讨论】:

        【解决方案5】:

        您的最后一个示例——带有“public test() { int i=0; }”的示例可能无法按预期工作。通过在 test 和 addi 中重新声明变量“int”,您现在拥有三个名为“i”的变量:定义在顶部的成员变量、test 中的局部变量和 addi 中的另一个局部变量。任何一个函数都不会更改成员值。

        我肯定会避免使用虚拟值初始化变量,例如您的“contact1=new String()”。是的,这可以防止您收到未初始化变量的编译错误或可能引发空指针异常。但是如果你没有这个就得到一个错误,那么这一定意味着你没有把一个真正的值放入变量中。设置虚拟值并不能解决问题,它只是隐藏它。这就像将胶带贴在仪表板上的警告灯上:是的,您不再看到警告,但这并不是因为问题已解决,而只是因为您掩盖了它。

        在某些情况下,设置默认值是有意义的,然后您可能会将其替换为其他值,而您可能不会。我并不是说这是一种不好的做法。我的意思是,如果您对未初始化的变量出错,请不要盲目地将它们初始化为无意义的东西。找出它们没有价值的原因并解决真正的问题。

        除此之外,我不知道该对您的示例说些什么。我不确定你想要完成什么。您有名为contact1、contact2 和contact3 的变量,这些变量似乎从未使用过。 contactArray 显然应该由 fillContactsGui 填充,但我看不到它在哪里被调用过。我不确定这些是你的逻辑缺陷还是这只是一个不完整的例子。

        关于初始化和使用数据的一般正确方法:

        如果一个变量可以是本地的,就让它成为本地的。在这种情况下,理想情况下在您声明它时对其进行初始化。喜欢:

        public void foobar()
        {
          ... do some stuff ...
          int i=0;
          ... do other stuff ...
          i=i+j;
          ... etc ...
        }
        

        如果可能的话,我会避免定义它,然后再对其进行初始化,因为这可能会导致您无法初始化它。当然,如果它可能以两种不同的方式进行初始化,这是很难避免的。喜欢:

        public void foobar()
        {
          int i;
          if (plugh>0)
            i=plugh;
          ... bunch more logic ...
          // Inside some IF so we won't even get here if i was set earlier
          if (zork==true)
            i=shambar;
          ... etc ...
        }
        

        不过,你越能保持在一起越好。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-10-24
          • 2019-10-03
          • 2023-03-06
          • 1970-01-01
          相关资源
          最近更新 更多