0

I could not understand Java's annotation's default value.

This is my code:

import cn.hutool.core.util.ReflectUtil;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

public class Question {

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    @interface Test {

        String name = "123";

        String name() default name;

    }

    @Test
    private final String demo = null;

    public static void main(String[] args) {
        System.out.println(System.identityHashCode(Test.name));
        System.out.println(System.identityHashCode(
                ReflectUtil.getField(Question.class, "demo").getAnnotation(Test.class).name())
        );
    }
}

The result is:

1147985808
1789447862

Why is the same object's system hashCode different?

khelwood
  • 55,782
  • 14
  • 81
  • 108
Forever
  • 31
  • 2
  • Because it isn't the same object. They are equal but not the same object. – M. Deinum Jul 12 '22 at 09:05
  • They are not the same object? Like my code, I think they are point to the `Test.name`. they should be the same object. – Forever Jul 12 '22 at 09:18
  • I suggest you take a look with the decompiler. `name` is a constant, where `name()` is the attribute of an annotation. It will use a copy of the constant not a reference (if it would use a reference they would have the same hashCode wouldn't they). – M. Deinum Jul 12 '22 at 09:47
  • Thranks, I have take a look with JetBrain's decoplier , and I also have used JetBrain's 'Show Bytecode' . But I do not find `copy` was used. – Forever Jul 12 '22 at 12:35
  • And I do want to know why the annotation's default value do not use Java’s String Constant Pool. – Forever Jul 12 '22 at 12:44
  • Where I was mentioning decompiler I was referring to `javap` which can show the generated bytecode, which makes this clear. This is probably somewhere in the language spec (or a miss) that is should clone/copy the value. In case of a mutable value if it was shared this would lead to issues. – M. Deinum Jul 12 '22 at 13:15

1 Answers1

0

That is because System.identityHashCode() method doesn't returns the actual hashcode, it just returns the hashcode based on object class's implementation not actual object specific. Try below and you will see the same hashcode value-

System.out.println(Test.name.hashCode());
System.out.println(ReflectUtil.getField(Question.class, "demo").getAnnotation(Test.class).name().hashCode());

Also for more understanding try overriding hashcode method in your Question class like below-

    public int hashCode(){
    return 1;
    }

Then when you will call hashcode() method on any Question class object it will always give you 1 but System.identityHashCode() method still will give you some random values.