静态变量是从仅初始化一次的文件初始化的

时间:2015-05-29 15:12:03

标签: java static

我在Java中创建一个表示String和Color的类,称为ColoredString。我希望能够使用.Net框架识别的任何颜色的颜色名称创建其中一个对象。这样的颜色列表在这里:http://www.simplehtmlguide.com/colours.php。由于Java没有全面的“已知颜色”列表,我的解决方案是从文件中读取我的程序以填充要使用的已知颜色列表。所以,我按照这种格式制作了一个文本文件:

AliceBlue #F0F8FF
AntiqueWhite #FAEBD7
Aqua #00FFFF
Aquamarine #7FFFD4

第一个单词是颜色名称,第二个单词是#RRGGBB格式,用于指定颜色代码。因为每次我调用一个ColoredString的构造函数时,我显然不想从文件中读取,我想我可能会将它读入一个静态变量,希望当我的程序运行时,这个文件将被读取一次并创建这个静态变量的单个实例,由ColoredString的任何实例引用。这是我写的代码:

import java.awt.Color;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;

public class ColoredString {

    public static final ArrayList<KnownColor> knownColors = setKCs();

    private static ArrayList<KnownColor> setKCs() {
        try (Scanner scanner = new Scanner(new File("dotNet_knownColors.txt"));) {
            ArrayList<KnownColor> knownColors = new ArrayList<>();
            while (scanner.hasNextLine()) {
                String colorName = scanner.next().toLowerCase();
                String colorCode = scanner.next().toUpperCase();
                knownColors.add(new KnownColor(colorName, colorCode));
            }
            return knownColors;
        } catch (FileNotFoundException fnfex) {
            System.out.println("uh-oh...");
        }
        return null;
    }
    public static final String defaultColor = "black";
    private Color color;
    private String string;

    public ColoredString(String color, String string) {
        if (color == null || color.equals("")) {
            color = defaultColor;
        }
        color = color.toLowerCase();
        this.string = string;
        if (color.startsWith("#")) {
            this.color = new Color(Integer.parseInt(color.substring(1), 16));
        } else {
            this.color = getColorByName(color);
        }
    }

    public ColoredString(String string) {
        this.string = string;
        this.color = getColorByName(defaultColor);//default color

    }

    private static Color getColorByName(String name) {
        for (KnownColor c : knownColors) {
            if (c.name.equals(name)) {
                String colorCode = c.rgbHexNum;
                return new Color(Integer.parseInt(colorCode.substring(1), 16));
            }
        }
        return getColorByName(defaultColor);
    }

    private static class KnownColor {

        public final String name;
        public final String rgbHexNum;

        public KnownColor(String name, String rgbHexNum) {
            this.name = name;
            this.rgbHexNum = rgbHexNum;
        }
    }
}

所以我的问题是:我的代码会按照我的说法执行,只读取一次文件,并且只创建一个变量knownColors的单个实例,即使我创建了很多类的实例吗?

2 个答案:

答案 0 :(得分:1)

简单介绍一下......是的。

如果您想确定,为什么不在从文件加载的代码中使用断点调试程序并查看它被击中的频率?或者在该代码中暂时向System.out.println添加一些代码。

答案 1 :(得分:0)

首先检查Java。下面是java 8;我使用javafx.scene.paint.Color,因为Oracle认为JavaFX是AWT / Swing的继承者。

它可以做148种颜色名称。

首先测试你的颜色:

    String[] colorNames = { "aquamarine", "Aquamarine", "AntiqueWhite" };
    // List with color as hex, with alpha component as FF
    for (String colorName : colorNames) {
        Color color = Color.valueOf(colorName);
        System.out.printf("%s -> %s%n", colorName, color);
    }

然后是所有颜色常数:

    for (Field field : Color.class.getDeclaredFields()) {
        int modifiers = field.getModifiers();
        if (Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers)
                && Modifier.isFinal(modifiers) && field.getType() == Color.class) {
            String colorName = field.getName().toLowerCase(Locale.US);
            Color color = Color.valueOf(colorName);
            System.out.printf("- %s -> %s%n", colorName, color);
        }
    }

这使用反射,并假设常量名称是人类可读的名称。

[139] thistle -> 0xd8bfd8ff
[140] tomato -> 0xff6347ff
[141] turquoise -> 0x40e0d0ff
[142] violet -> 0xee82eeff
[143] wheat -> 0xf5deb3ff
[144] white -> 0xffffffff
[145] whitesmoke -> 0xf5f5f5ff
[146] yellow -> 0xffff00ff
[147] yellowgreen -> 0x9acd32ff