Java 私有字符串成员使用什么初始化

Java 私有字符串成员使用什么初始化,java,Java,在Java中,初始化私有字符串成员的最佳实践是什么 class A { private String mem = ??// private int num; A (int a) { this.num = a; } A (int a, String s) { this.num = a; this.mem = s; //What if s is null (Is t

在Java中,初始化私有字符串成员的最佳实践是什么

class A {
       private String mem = ??//
       private int num;
       A (int a) {
          this.num = a;
       }
       A (int a, String s) {
           this.num = a;
           this.mem  = s; //What if s is null (Is this a good practice)
       }

}

简言之,没有最佳实践

取决于你的型号。某些字符串可能需要为空,而其他字符串(强制)应始终包含值。有时不仅仅是一个空字符串


我不会盲目地将空字符串分配给所有内容。

将其留空:
private string mem


关于“如果s为null怎么办”,我们应该强调在有效状态下构造所有对象。但是什么是“有效的”完全取决于你的应用程序。当程序的其余部分引用
mem
并发现它是
null
时,会发生什么?最好是空字符串还是其他默认值?它因环境而异。

您应该定义一个合同,然后对其进行编码。如果允许该成员为null,则将其初始化为null。如果不是,通常初始化为空字符串
是个好主意。但同样,这取决于您的数据模型,有时空字符串也是无效的


在所有情况下,如果传入无效字符串,则构造函数应该抛出
NullPointerException
IllegalArgumentException

这取决于该属性的使用情况

空值是否为程序中的有效输入

如果不是,那么你应该验证它并抛出一个Npe

A ( int a, String s  ) { 
    if( s == null ) { 
        throw new NullPointerException("The value of s cannot be null"); 
    }
    ....
}
如果它是一个有效值,那么就不会有问题


虽然这是一个很好的做法,但是您只在一个位置分配值,因此如果您在构造函数中进行验证,您不会感到意外,但随后设置程序会更改值。

如果字符串永远不应该为null,那么从参数设置它的构造函数应该在参数为null时引发异常,另一个构造函数应该将其设置为有用的默认值。

完全取决于您正在做什么

问自己这些问题(无论何时你做任何变量)

  • 价值会改变吗
  • 允许值是多少
在这种情况下,如果“mem”和“num”永远不会更改,那么将它们标记为final(如果您发现必须更改它们,您可以随时删除final)

在这种情况下,“mem”是否可以为null?num是否可以小于0

以下是我可能做出的更改示例:

甲级 { 私有最终字符串mem; 私有整数

   A (final int a) 
   {
       this(a, null); 
   }

   A (final int a, 
      final String s) 
   {
       if(a < 0)
       {
           throw new IllegalAgumentException("a cannot be < 0, was: " + a);
       }

       num = a;
       mem = s; 
   }
A(最终整数A)
{
这(a,空);
}
A(最终int A,
最终字符串(s)
{
if(a<0)
{
抛出新的IllegalgumentException(“a不能小于0,was:+a);
}
num=a;
mem=s;
}

}

这其中有一个技巧(实际上,大多数变量也是如此)

如果您从未初始化变量,那么实际上是在向编译器提供更多信息

在某些情况下,您必须这样做,但这个案例非常有趣:

String s;

if(a==5)
    s="It was Five";
if(a==6)
    s="It was Six";

System.out.print(s);
这是一段非常糟糕的代码,但最妙的是,Java会捕捉到它,并告诉您“嘿,很有可能您会在打印时使用空值”

如果您从以下两行中的任何一行开始:

String s=null;
String s="";
编译器不可能帮你解决那个错误。(您不太可能打算打印“”,是吗?)

当您看到此“变量可能尚未初始化”消息时,正确的修复方法不是将字符串初始化为null或“”。实际上,要确保在每个可能的路径中将s设置为有效值:

if(a==5)
    s="It was Five";
else if(a==6)
    s="It was Six";
else
    s="It was something else, who knows?";
这将很好地编译,即使不初始化s。这适用于复杂的if/else、循环和异常情况,所以不要仅仅假设它只会捕获像这样的琐碎情况

所以“最佳实践”是永远不要将变量初始化为“”、0或null。不要初始化它们,除非它真的有意义,并且您正在以某种方式使用您设置的值


一旦在我的例子中得到错误,你可以将s初始化为“It was other,who know?”而不是添加else,这将是完全有效的;但习惯上不将其初始化为null或“”,至少它能够提醒您必须这样做。

如果字符串永远不应该为null,则可以将其声明为final,这样编译器可以确保所有构造函数都为其赋值

class A {
   private final String mem;
   private int num;
   A (int a) {
      this.num = a; // <= compile error, mem must be assigned
   }
   A (int a, String s) {
       this.num = a;
       this.mem  = s; // <= you need to null-check yourself
   }
}
A类{
私有最终字符串mem;
私有整数;
A(INTA){

this.num=a;//将其保留为空与初始化为null(final成员除外)相同。将参数设置为final的目的是什么?它阻止您意外执行a=num;或s=mem;它还与“值是否会更改?”问题。参数几乎从未被故意重新分配。else-if版本也允许您将其声明为“final String s;”