Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java类工作流_Java - Fatal编程技术网

Java类工作流

Java类工作流,java,Java,如果我有一个带有常量的类,例如AppConstants,并使用公共静态final变量,比如AppConstants.MY_STRING,它会一直重新创建这个类,或者在运行时创建它,因为类中的字段是静态的?所以,最好是在常量中定义文件还是在指定的位置定义文件?类加载程序会加载一次类,通常在需要时加载1。加载一个类时,它的所有静态成员也会加载,并与该类一起使用,而不是与该类的特定对象引用一起使用。多次使用该类的静态字段不会重新加载该类。重新加载类的唯一方法是使用自定义类装入器 在常量中定义文件更好还

如果我有一个带有常量的类,例如AppConstants,并使用公共静态final变量,比如AppConstants.MY_STRING,它会一直重新创建这个类,或者在运行时创建它,因为类中的字段是静态的?所以,最好是在常量中定义文件还是在指定的位置定义文件?

类加载程序会加载一次类,通常在需要时加载1。加载一个类时,它的所有静态成员也会加载,并与该类一起使用,而不是与该类的特定对象引用一起使用。多次使用该类的静态字段不会重新加载该类。重新加载类的唯一方法是使用自定义类装入器

在常量中定义文件更好还是在位置上定义文件更好

将它们定义为类上的静态最终字段或使用枚举

1需要时的定义:

如果像这样声明基元或字符串常量:

public class AppConstants {
    public static final int ONE = 1;
    public static final int TWO = 2;
    public static final int TEN = 10;
}

public class ClientTest {
    public static void main(String[] args) {
        System.out.println(AppConstants.ONE);
        System.out.println(AppConstants.TWO);
        System.out.println(AppConstants.TEN);
    }
}
编译这两个类并执行ClientTest时,AppConstants类不会使用HotSpot进行加载测试,因为编译器将内联这些常量。为了评估结果,请执行以下操作:

> javac -cp:. AppConstants.java ClientTest.java
> javap -c ClientTest //you can see the generated bytecode
> java -verbose:class ClientTest //shows you the classes loaded to execute this app
你会看到这个

来自javap-c ClientTest的正确代码:

public static void main(java.lang.String[]);
  Code:
   0:   getstatic   #2; //Field java/lang/System.out:Ljava/io/PrintStream;
   3:   iconst_1 //My Comment: constant with value 1
   4:   invokevirtual   #3; //Method java/io/PrintStream.println:(I)V
   7:   getstatic   #2; //Field java/lang/System.out:Ljava/io/PrintStream;
   10:  iconst_2 //My Comment: constant with value 2
   11:  invokevirtual   #3; //Method java/io/PrintStream.println:(I)V
   14:  getstatic   #2; //Field java/lang/System.out:Ljava/io/PrintStream;
   17:  bipush  10 //My Comment: constant with value 10
   19:  invokevirtual   #3; //Method java/io/PrintStream.println:(I)V
   22:  return

}
来自java-verbose:class ClientTest:

现在提供java-verbose:class ClientTest的相关输出:


@我要说的是,这个问题是相关的,但并没有回答OP的问题,因为OP询问类加载。@LuiggiMendoza-这个问题的第一个答案是:每个类加载程序一个。似乎它直接回答了这个问题,但如果不是重复的话,在过去的6年里还有其他几个答案,也许,或者,或者……对不起,如果你认为我很恶劣,我真的不是,它是为了帮助人们更容易地找到正确的答案,通常有两个问题。@AndyBrown您提供的链接谈论静态成员。请理解OP的查询不是100%与静态成员相关,更多的是关于类加载。虽然解释了回答这个问题的概念,但它并没有直接做到这一点。因此OP提出了一个问题并得到了直接的答案。如果你仍然反对这一点,那么就提出一个问题并询问。我建议你再次回顾我的答案,以便更好地理解在需要时加载类意味着什么。除了重复的讨论之外,这有点误导。AFAIK公共静态最终变量的使用实际上是由编译器在可能的情况下内联的,因此相应的类根本没有通过此类引用加载。@AndyBrown我不明白您的评论有什么误导性。OP说:如果我有一个带有常量的类。。。并使用。。。从那里像AppConstants.MY_字符串一样,它会一直重新创建这个类,还是在运行时创建它,因为类中的字段是静态的?在他的特定情况下,它根本不会创建那个类——常量将被内联。在你的回答中你说。。。需要时,但不要解释在这种情况下不会加载它,因为它不是必需的。@AndyBrown如果您有一个类AppConstants,但不使用它,则不会加载它。如果您有这样一行字符串s=AppConstants.MY_字符串,并且执行了这一行,那么将使用AppConstants类,因此它将被加载一次,因为需要该类。这正是我的观点-如果这就是您所做的全部,那么该类将不会被加载。常量是内联的,因此类加载器不会加载该类。试试看,如果你愿意,我可以给你发密码。
[Opened C:\Program Files\Java\jre1.8.0_51\lib\rt.jar]
[Loaded java.lang.Object from C:\Program Files\Java\jre1.8.0_51\lib\rt.jar]
// Lots of classes from rt.jar
[Loaded java.security.UnresolvedPermission from C:\Program Files\Java\jre1.8.0_51\lib\rt.jar]
[Loaded java.security.BasicPermissionCollection from C:\Program Files\Java\jre1.8.0_51\lib\rt.jar]
[Loaded ClientTest from file:/D:/tmp/] //<-- Class being executed
[Loaded sun.launcher.LauncherHelper$FXHelper from C:\Program Files\Java\jre1.8.0_51\lib\rt.jar]
[Loaded java.lang.Class$MethodArray from C:\Program Files\Java\jre1.8.0_51\lib\rt.jar]
[Loaded java.lang.Void from C:\Program Files\Java\jre1.8.0_51\lib\rt.jar]
1
2
10
[Loaded java.lang.Shutdown from C:\Program Files\Java\jre1.8.0_51\lib\rt.jar]
[Loaded java.lang.Shutdown$Lock from C:\Program Files\Java\jre1.8.0_51\lib\rt.jar]
public class AppConstants {
    public static final int ONE = 1;
    public static final int TWO = 2;
    public static final int TEN = 10;
    public static final List<String> NAMES = Collections.unmodifiableList(Arrays.asList("Luiggi", "Andy"));
}

public class ClientTest {
    public static void main(String[] args) {
        System.out.println(AppConstants.ONE);
        System.out.println(AppConstants.TWO);
        System.out.println(AppConstants.TEN);
        System.out.println(Foo.NAMES);
    }
}
//...
[Loaded ClientTest from file:/D:/tmp/] //our class being executed
[Loaded sun.launcher.LauncherHelper$FXHelper from C:\Program Files\Java\jre1.8.0_51\lib\rt.jar]
[Loaded java.lang.Class$MethodArray from C:\Program Files\Java\jre1.8.0_51\lib\rt.jar]
[Loaded java.lang.Void from C:\Program Files\Java\jre1.8.0_51\lib\rt.jar]
1  //output of constants
2
10
[Loaded AppConstants from file:/D:/tmp/] //loads AppConstants class here because it's needed
[Loaded java.util.Arrays$ArrayList from C:\Program Files\Java\jre1.8.0_51\lib\rt.jar]
[Loaded java.util.AbstractList$Itr from C:\Program Files\Java\jre1.8.0_51\lib\rt.jar]
[Luiggi, Andy] //output of AppConstants#NAMES