-2

Let's say I defined a constant int in file A.java:

public final static int CONSTAN_VALUE_IN_A = 0;

when I use this value in another file B.java:

int fooBValue = A.CONSTAN_VALUE_IN_A;

after I compiled my project, in B.class,I have:

fooBValue = 0

I want to know if I can get where the value "0" come from (A.java) when I only have B.class file without the source code. I heard that when compile with java8, I can know that B.java use some constant value in A.java by reading the constant pool in B.class. But I'm not really sure about that or how to get the actual class the constant come from by reading the constant pool.

  • 1
    `I want to know if I can get where the value "0" come from` what exactly do you mean? – Procrastinator Sep 13 '17 at 15:14
  • 1
    Value is a value, it can not "come from". There is a sense of speaking about same values for the reference type variables, but not in this context. – Andremoniy Sep 13 '17 at 15:21
  • @procrastinator "come from" means where this constant value defined. – Raymond Guo Sep 14 '17 at 08:35
  • @Andremoniy yes kind of like reference, I just want to know when I read the B.class file, How can I know the value 0 "come from" A.class. forgive my pool kill of expression. – Raymond Guo Sep 14 '17 at 08:37
  • @Raymond Didn't you define it yourself? Because your question states so `Let's say I defined a constant int in file A.java`. – Procrastinator Sep 14 '17 at 08:46
  • @procrastinator see my edit with bold characters, I mean when the project is not written by me and I do not have the source code, only the B.class file. How Can I know the "come from" info?so, I mainly want to know how to analyze my class file. – Raymond Guo Sep 15 '17 at 07:49

2 Answers2

3

JLS 4.12.4 defines a "constant variable" as follows:

A constant variable is a final variable of primitive type or type String that is initialized with a constant expression (§15.28).

JLS 13.1 describes how these end up in a class file:

3. A reference to a field that is a constant variable (§4.12.4) must be resolved at compile time to the value V denoted by the constant variable's initializer.

If such a field is static, then no reference to the field should be present in the code in a binary file, including the class or interface which declared the field. Such a field must always appear to have been initialized (§12.4.2); the default initial value for the field (if different than V) must never be observed.

The declaration in class A

    public final static int CONSTAN_VALUE_IN_A = 0;

meets the definition of a constant variable, so when it's used in class B,

    int fooBValue = A.CONSTAN_VALUE_IN_A;

the value is resolved at compile time. No reference to A.CONSTAN_VALUE_IN_A appears in class B, and instead the resolved value of 0 is compiled into class B.

So, no, there's no way to tell where that value in B came from unless you can find the source code.

If you don't like this behavior, you can avoid it by changing things so that the conditions of JLS 4.12.4 aren't met, such as by making it not final, or by changing the type so that it's neither a primitive nor a String. However, the easiest way of making it not a constant variable is to move the initialization into a static initializer:

    public final static int CONSTAN_VALUE_IN_A;
    static {
        CONSTAN_VALUE_IN_A = 0;
    }

By the way, this is not new in Java 8; this behavior has been this way for a very long time.

Community
  • 1
  • 1
Stuart Marks
  • 127,867
  • 37
  • 205
  • 259
-1

Almost certainly not.

Many static final values are even replaced at compile time by the actual value associated with the constant.

static final int X = 0;
static final int Q = 9;

private void test(String[] args) {
    int x = X;
    int y = Q;
}

would probably be transformed in the very early stages of compilation into:

private void test(String[] args) {
    int x = 0;
    int y = 9;
}

so the chances of discovering where the value actually came from are very small.

OldCurmudgeon
  • 64,482
  • 16
  • 119
  • 213
  • While I am not a downvoter of your answer, for me the question itself does not make any sense; – Andremoniy Sep 13 '17 at 15:27
  • Your answer boils down to _Almost certainly not._ The rest they've already mentioned in their question: _after I compiled my project, in B.class,I have [...]_. – Sotirios Delimanolis Sep 13 '17 at 15:31
  • @Andremoniy - My interpretation of *I want to know if I can get where the value "0" come from (A.java)* is can OP tell that the resultant value of `fooBValue` (i.e. the `0`) came from the `A` class. – OldCurmudgeon Sep 13 '17 at 16:09
  • @SotiriosDelimanolis - Exactly my point - the source is truly gone well before the class file is built and certainly will not be available at run-time. – OldCurmudgeon Sep 13 '17 at 16:10
  • My point is you're just repeating what they've already said, and you're not doing it convincingly. Edit your answer to provide proof and evidence instead of guessing, _almost certainly_, _chances are very small_, _probably_. – Sotirios Delimanolis Sep 13 '17 at 16:12