When you place an annotation on a variable, it becomes a static property of that variable, not of the object you can reach through that variable. Consider:
public class A1 extends myA{
@Test("all")
private B b1=new B();
@Test("none")
private B b2=b1;
//....
public void interact(){
// this
b2.doSomethingBasedOnMyAnnotation();
// is exactly the same as
b1.doSomethingBasedOnMyAnnotation();
}
}
It’s not even valid to assume that there is an annotated variable involved. What about
new B().doSomethingBasedOnMyAnnotation()
?
Since fields are resolved at compile-time, there is no abstraction in your desired operation anyway. If you know that you are going to invoke, b2.doSomethingBasedOnMyAnnotation();
, you already know which field you’re using and there’s no problem of providing the annotation value of b2
as parameter to the invoked method, rather than expecting the receiver to magically find out. E.g.
public class B{
public void doSomething(String arg){
}
}
public class A1 extends myA{
@Test("all")
private B b1;
@Test("none")
private B b2;
//....
public void interact(){
b1.doSomething(get("b1"));
b2.doSomething(get("b2"));
}
static String get(String fieldName) {
try {
return A1.class.getDeclaredField(fieldName)
.getAnnotation(Test.class).value();
} catch(NoSuchFieldException ex) {
throw new IllegalStateException(ex);
}
}
}
though we could happily work without Reflection:
public class A1 extends myA{
static final String TEST_B1="all";
@Test(TEST_B1)
private B b1;
static final String TEST_B2="none";
@Test(TEST_B2)
private B b2;
static final String TEST_B3="none";
@Test(TEST_B3)
private B b3;
//....
public void interact(){
b1.doSomething(TEST_B1);
b2.doSomething(TEST_B2);
}
}
If you want to make sure that the caller can’t pass the wrong argument by accident, use encapsulation instead:
public final class EncapsulatedB {
final String testValue;
B b;
EncapsulatedB(String value) {
this(value, null);
}
EncapsulatedB(String value, B initialB) {
testValue=value;
b=initialB;
}
public B getB() {
return b;
}
public void setB(B b) {
this.b = b;
}
public void doSomething() {
b.doSomething(testValue);
}
}
public class A1 extends myA{
private final EncapsulatedB b1=new EncapsulatedB("all");
private final EncapsulatedB b2=new EncapsulatedB("none");
private final EncapsulatedB b3=new EncapsulatedB("none");
//....
public void interact(){
b1.doSomething();
b2.doSomething();
}
}