Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/358.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静态final字段是否将被对齐?_Java_Reflection_Field - Fatal编程技术网

使用反射,我是否可以确定Java静态final字段是否将被对齐?

使用反射,我是否可以确定Java静态final字段是否将被对齐?,java,reflection,field,Java,Reflection,Field,是否有任何方法可以使用反射来确定静态final字段是否具有“=”值(以便在访问该字段时该值将以行形式显示)或其值是否由静态初始值设定项指定? 如果字段确实有值,是否有任何方法可以在不使用field.get方法的情况下检索该值(从而导致执行静态初始值设定项)?仅当字段是编译时常量时,该字段才会“内联”-请参阅中的详细定义 因此,在声明时分配它是不够的。 这不是编译时常量,但声明有效: static final int INT_CONST = compute(); static int compu

是否有任何方法可以使用反射来确定静态final字段是否具有“=”值(以便在访问该字段时该值将以行形式显示)或其值是否由静态初始值设定项指定? 如果字段确实有值,是否有任何方法可以在不使用field.get方法的情况下检索该值(从而导致执行静态初始值设定项)?

仅当字段是编译时常量时,该字段才会“内联”-请参阅中的详细定义

因此,在声明时分配它是不够的。 这不是编译时常量,但声明有效:

static final int INT_CONST = compute();

static int compute() {
    return 5;
}
仅仅通过反射,您无法确定字段是如何初始化的


要访问类字段的任何值,需要首先加载该类,因此不能阻止静态初始值设定项运行。

不能通过反射来执行此操作,但可以使用字节码工程库执行此操作,如:


谢谢,ASM听起来是个不错的选择。我假设ASM代码不会导致执行静态初始值设定项?@RobertSales,不,它只是将其读取为
字节[]
数组。这样,即使应用程序中根本没有加载任何类,它也可以读取任何类。
public class AsmTest {
    static final int a = 2; // constant
    static final String b = "string"; // constant
    static final String c = "foo "+"bar"; // constant: concatenation is allowed
    static final String d = " foobar ".trim(); // not constant: method called

    public static Object getFieldConstantValue(Class<?> clazz, final String field) {
        try(InputStream is = clazz.getResourceAsStream(clazz.getSimpleName()+".class")) {
            final Object[] value = {null};
            new ClassReader(is).accept(new ClassVisitor(Opcodes.ASM5) {
                @Override
                public FieldVisitor visitField(int access, String name, String desc,
                        String sig, Object val) {
                    if(name.equals(field))
                        value[0] = val;
                    return null;
                }
            }, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
            return value[0];
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {
        for(String name : new String[] {"a", "b", "c", "d"}) {
            System.out.println(name+"="+getFieldConstantValue(AsmTest.class, name));
        }
    }
}
a=2
b=string
c=foo bar
d=null