在Java中,何时为实例变量赋值合适?
这是一个关于最佳做法的问题。当采用面向对象的方法时,我想出了三种不同的方法来做同样的事情。在我未经训练的眼中,它们似乎都没有“错误”,但我知道每种语言和风格都有其最佳实践,我想知道这三种方式中是否有任何一种违反了我尚未学会的“最佳实践” 方式1:(声明,然后在构造函数中赋值) 方式2:(同时声明和分配) 方式3:(有些东西是在非get/set方法中初始化的)在Java中,何时为实例变量赋值合适?,java,oop,instance-variables,Java,Oop,Instance Variables,这是一个关于最佳做法的问题。当采用面向对象的方法时,我想出了三种不同的方法来做同样的事情。在我未经训练的眼中,它们似乎都没有“错误”,但我知道每种语言和风格都有其最佳实践,我想知道这三种方式中是否有任何一种违反了我尚未学会的“最佳实践” 方式1:(声明,然后在构造函数中赋值) 方式2:(同时声明和分配) 方式3:(有些东西是在非get/set方法中初始化的) 就我个人而言,对于这项具体的家庭作业,我非常喜欢第三种方式,因为它符合我试图解决的问题的逻辑。但这是错误的,嗯,这是错误的…第二个版本似乎
就我个人而言,对于这项具体的家庭作业,我非常喜欢第三种方式,因为它符合我试图解决的问题的逻辑。但这是错误的,嗯,这是错误的…第二个版本似乎还可以。但常数确实是静态的最终字符串
public class CCipher {
private static final String ALPHABET = "abcdefghijklmnopqrstuvwxyz";
private final String shiftedAlphabet;
private final int mainKey;
public CCipher(int key) {
mainKey = key;
shiftedAlphabet = ALPHABET.substring(mainKey)
+ ALPHABET.substring(0, mainKey);
}
克里斯托弗·施奈德(Christopher Schneider)指出,在加密和解密中使用了不同的移位字母表。实际上,作为一个CCipher对象,可能需要加密或解密,所以将其设置为局部变量 需要两个不同的非最终延迟初始化字段,这很麻烦
public class CCipher {
private static final String ALPHABET = "abcdefghijklmnopqrstuvwxyz";
//private final String shiftedEncryptAlphabet;
//private final String shiftedDecryptAlphabet;
private final int mainKey;
public CCipher(int key) {
mainKey = key;
shiftedAlphabet = ALPHABET.substring(mainKey)
+ ALPHABET.substring(0, mainKey);
}
public String encrypt(String input){
String shiftedAlphabet = alphabet.substring(mainKey)
+ alphabet.substring(0, mainKey);
// ... code to encrypt input ...
}
public String decrypt(String input){
String shiftedAlphabet = alphabet.substring(26 - mainKey)
+ alphabet.substring(0, 26 - mainKey);
// ... code to decrypt input
}
第二个版本似乎还可以。但常数确实是静态的最终字符串
public class CCipher {
private static final String ALPHABET = "abcdefghijklmnopqrstuvwxyz";
private final String shiftedAlphabet;
private final int mainKey;
public CCipher(int key) {
mainKey = key;
shiftedAlphabet = ALPHABET.substring(mainKey)
+ ALPHABET.substring(0, mainKey);
}
克里斯托弗·施奈德(Christopher Schneider)指出,在加密和解密中使用了不同的移位字母表。实际上,作为一个CCipher对象,可能需要加密或解密,所以将其设置为局部变量 需要两个不同的非最终延迟初始化字段,这很麻烦
public class CCipher {
private static final String ALPHABET = "abcdefghijklmnopqrstuvwxyz";
//private final String shiftedEncryptAlphabet;
//private final String shiftedDecryptAlphabet;
private final int mainKey;
public CCipher(int key) {
mainKey = key;
shiftedAlphabet = ALPHABET.substring(mainKey)
+ ALPHABET.substring(0, mainKey);
}
public String encrypt(String input){
String shiftedAlphabet = alphabet.substring(mainKey)
+ alphabet.substring(0, mainKey);
// ... code to encrypt input ...
}
public String decrypt(String input){
String shiftedAlphabet = alphabet.substring(26 - mainKey)
+ alphabet.substring(0, 26 - mainKey);
// ... code to decrypt input
}
关于
字母表
——如果它从未改变,第二个代码片段可能最接近最佳实践,但它仍然不在那里——它应该是一个私有静态final
“常量”:
关于shiftedAlphabet
——第三个片段肯定不太有利(尽管从技术上讲不是“错误”)——在每次调用encrypt
或decrypt
时,您都会重新计算shiftedAlphabet
,它不会受到输入的任何影响。它可能没有错,但它是浪费的(换句话说,作为一名教师,我肯定会为此推断出一些要点,即使代码确实有效)
总而言之,第二个代码段可能是这三个代码段中最好的,但我会将字母表
的修饰符修改为私有静态最终版
关于字母表
,如果不改变,第二个代码段可能最接近最佳实践,但它仍然不在那里-它应该是一个私有静态final
“常量”:
关于shiftedAlphabet
——第三个片段肯定不太有利(尽管从技术上讲不是“错误”)——在每次调用encrypt
或decrypt
时,您都会重新计算shiftedAlphabet
,它不会受到输入的任何影响。它可能没有错,但它是浪费的(换句话说,作为一名教师,我肯定会为此推断出一些要点,即使代码确实有效)
总而言之,第二个代码段可能是三个代码段中最好的,但是我会将字母表的修饰符修改为私有静态final
当CCipher
对象初始化时,您的第三个方法将移位字母表保留为null
;这最终可能会导致使用它并希望该值不为null
的用户出现问题。另外两种主要是个人偏好。对于第三种方式,shiftedAlphabet
仅在分配给它的方法中内部使用,因此不需要将其作为字段;最好将其设置为局部变量。为什么不声明alphabet=“abcdefghijklmnopqrstuvwxyz”代码>作为私有静态最终字符串
?以后是否有可能更改?是否首先需要有主键字段?除了在构造器中,它似乎没有在任何地方使用。嗨@NickAth,我怀疑它以后会改变,除非我自发地学习俄语。我还没有学会“final”,尽管我的IDE一直怂恿我使用它。当CCipher
对象初始化时,您的第三种方法将shiftedAlphabet
保留为null
;这最终可能会导致使用它并希望该值不为null
的用户出现问题。另外两种主要是个人偏好。对于第三种方式,shiftedAlphabet
仅在分配给它的方法中内部使用,因此不需要将其作为字段;最好将其设置为局部变量。为什么不声明alphabet=“abcdefghijklmnopqrstuvwxyz”代码>作为私有静态最终字符串
?以后是否有可能更改?是否首先需要有主键字段?除了在构造器中,它似乎没有在任何地方使用。嗨@NickAth,我怀疑它以后会改变,除非我自发地学习俄语。虽然我的IDE一直在怂恿我使用它,但我还没有学会“最终版”,这正是我要说的。如果属性没有更改,请将它们标记为final,并在构造函数中初始化。@ChristopherSchneider。即使在3中,主键也似乎是固定的。因此,请准备常量,使所有内容都是最佳的。我忽略了这一点,因为它是一个类属性,而不是局部变量,但看起来shiftedAlphabet
是一个不断变化的变量。它应该是两个变量,例如shiftedAlphabetEncrypt
和Decrypt
。@ChristopherSchneider我监督了这一点。那么一个局部变量可能是最好的,因为同一个实例不太可能同时进行加密和解密。@JoopEggen谢谢。我想把你所有的答案结合起来。保留字母表
,并使其成为最终版本。去掉shiftedAlphabet变量并使其成为局部变量。让构造函数填写main键
,这正是我想要的
public class CCipher {
private static final String ALPHABET = "abcdefghijklmnopqrstuvwxyz";
//private final String shiftedEncryptAlphabet;
//private final String shiftedDecryptAlphabet;
private final int mainKey;
public CCipher(int key) {
mainKey = key;
shiftedAlphabet = ALPHABET.substring(mainKey)
+ ALPHABET.substring(0, mainKey);
}
public String encrypt(String input){
String shiftedAlphabet = alphabet.substring(mainKey)
+ alphabet.substring(0, mainKey);
// ... code to encrypt input ...
}
public String decrypt(String input){
String shiftedAlphabet = alphabet.substring(26 - mainKey)
+ alphabet.substring(0, 26 - mainKey);
// ... code to decrypt input
}
public class CCipher {
private static final String alphabet = "abcdefghijklmnopqrstuvwxyz";
// ...
}