使用for循环创建对象数组,for循环内属性正确,for循环外属性错误

Using for loop to create array of objects, attributes are correct inside for loop but wrong outside for loop

我想创建一个对象数组,每个对象包含三个属性(规则、标记、优先级)。

为此,我有一个 class,它包含单独数组中的所有属性 (GenRules.java),另一个 class 带有对象的构造函数 (Token.java).

这是我的一些代码 运行 但请注意 for 循环内和 for 循环外的输出有何不同:

public static void main( String[] args ) {

    // GenRules contains three arrays, one with the lexemes, another with their
    // corresponding tokens, and another with their priorities. They are separate
    // arrays but are related by index.
    int length = GenRules.length();

    // Generates an array of token objects containing all three attributes. 
    Token[] tok = new Token[ length ]; 
    for( int i = 0; i < length; i++ ) {
        tok[i] = Token.makeToken( GenRules.rules[i], 
                                  GenRules.tokens[i], 
                                  GenRules.priorities[i] );
        System.out.println( "i = " + i + ", " 
                                  + Token.getRule(tok[i]) + ", " 
                                  + Token.getToken(tok[i]) + ", " 
                                  + String.valueOf( Token.getPriority( tok[i] ) ) );
    }

    System.out.println( "\n" );
    int i = 0;
    for( Token t : tok ) {
        t = tok[i];
        System.out.println( "i = " + i + " " 
                + t.getRule(t) + " " 
                + t.getToken(t) + " " 
                + t.getPriority(t) );
        i++;
    }

}

for 循环内生成的输出是我希望看到的:

i = 0, /\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/, COMMENT, -1
i = 1, d+, NUMBER, 60
i = 2, int, TYPE_INT, 60
i = 3, char, TYPE_CHAR, 5
i = 4, main, MAIN, -1
.
.
.
i = 21, (, LP, 40
i = 22, ), RP, 40
i = 23, ==, EQUALVALUE, 20
i = 24, =, EQUALSIGN, 30

但在 for 循环之外,似乎所有对象都使用相同的三个属性进行了初始化:

i =  0 = EQUALSIGN 30
i =  1 = EQUALSIGN 30
i = 02 = EQUALSIGN 30
.
.
.
i = 22 = EQUALSIGN 30
i = 23 = EQUALSIGN 30
i = 24 = EQUALSIGN 30

知道我哪里出错了吗?为了完整起见,我将在下面添加其他两个 classes,请随意编织您看到的任何一般编码禁忌。

GenRules.java

package src;

/**
 * @author 
 * <p>
 * This class defines all of the lexing rules and tokens and has some helper functions to 
 * figure out how many rules currently exist. The arrays and values can be accessed statically, ie, no 
 * need to initialize a GenRules object. If the priority of a lexeme is 'None' it will return a '-1'. 
 * </p>
 */

public class GenRules {

/**
 * Regex comparison to a given token.
 */
public static String[] rules = { // 25 rules
        "/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/"        ,
        "d+"  ,"int","char","main"                       ,"return",
        "else","if" ,"for" ,"[_a-zA-Z][_a-zA-Z0-9]{0,31}","{"     ,
        "}"   ,";"  ,"<="  ,"<"                          ,">="    ,
        ">"   ,"+"  ,"-"   ,"*"                          ,"/"     ,
        "("   ,")"  ,"=="  ,"="
        };  

/**
 * Token issued to token at corresponding index.
 */
public static String[] tokens = { // 25 tokens
        "COMMENT"         ,"NUMBER"     ,"TYPE_INT" ,"TYPE_CHAR"    ,"MAIN",
        "RETURN"          ,"ELSE"       ,"IF"       ,"FOR"          ,"IDENTIFIER",
        "LB"              ,"RB"         ,"SEMICOLON","LESSTHANEQUAL","LESSTHAN",
        "GREATERTHANEQUAL","GREATERTHAN","PLUS"     ,"MINUS"        ,"MULTIPLY",
        "DIVIDE"          ,"LP"         ,"RP"       ,"EQUALVALUE"   ,"EQUALSIGN"
        };

/**
 * Priority issued to a corresponding token. 
 */
public static int[] priorities = { // 25 priorities
        -1,60,60, 5,-1,
        5 ,10,10,10, 8,
        9 ,10,70,20,20,
        20,20,70,70,65,
        65,40,40,20,30 
        };

/**
 * Prints how may tokens are currently defined. If there is a mismatch in how
 * many tokens there are in comparison to priorities or rules it will return '0'.
 */
public static int length() {
    if( priorities.length == tokens.length && tokens.length == rules.length )
        return rules.length;
    else return 0;
}

/**
 * Returns all of the rules components in array form.
 */
public static String[] returnRules() {
    return rules;

}

/**
 * Returns all of the token components in array form.
 */
public static String[] returnTokens() {
    return tokens;

}

/**
 * Returns all of the priorities in array form.
 */
public static int[] returnPriorities() {
    return priorities;

}

/**
 * Prints the rule followed by token, followed by priority. Isn't formatted very well. 
 */
public static String printRules(  ) {
    String out = "";
    for( int i = 0; i < priorities.length; i++ ) {
        out += rules[i] + " " + tokens[i] + " " + String.valueOf( priorities[i] ) + "\n";
    }
    return out;
}

}

Token.java:

package src;

/**
 * @author 
 *<p>
 *This class takes the rules, tokens, and priorities described in the GenRules
 *class and encapsulates them in a single object. A token can be thought of like
 *a struct which contains one rule, one token, and one priority level.
 *</p>
 */
public class Token {

private static String rule;
private static String token;
private static int priority;

public Token() {
    // Empty like my heart.
}

/**
 * Constructor; applies values to the class attributes. 
 * @param s1 rule
 * @param s2 token
 * @param i priority
 */
public Token( String s1, String s2, int i ) {
    rule = s1;
    token = s2;
    priority = i;
}

/**
 * Takes in arguments to construct a token and generates one
 * using the constructor. Once generated it is returned to 
 * wherever it was called from. 
 * @param s1
 * @param s2
 * @param i
 * @return Returns a formed token object.
 */
public static Token makeToken( String s1, String s2, int i ) {
    Token t = new Token( s1, s2, i );
    return t;
}

/**
 * Returns the rule from a Token.
 * @param t
 * @return
 */
public static String getRule( Token t ) {
    return t.rule.toString();
}

/**
 * Returns the 'token' from a Token.
 * @param t
 * @return
 */
public static String getToken( Token t ) {
    return t.token.toString();
}

/**
 * Returns the priority value from a Token.
 * @param t
 * @return
 */
public static String getPriority( Token t ) {
    return String.valueOf( t.priority );
}

/**
 * Will print out the rule, token, and priority values given
 * an array of tokens. 
 * @param t
 */
public static void printTokens( Token[] ti ) {
    for( Token t : ti ) {
        System.out.print( t.getRule( t ) + " " );
        System.out.print( t.getToken( t ) + " " );
        System.out.print( t.getPriority( t ) + "\n" );
    }
}

}

您在 Token class 中的变量是 static,因此它们属于 class,而不属于每个单独的 Token 对象。每次您设置这些变量时,它都会覆盖最后一个值(这就是为什么它总是打印您分配的最后一个值)。

private static String rule;
private static String token;
private static int priority;

删除 static 关键字并重试。

private String rule;
private String token;
private int priority;