How to access a class field in a complicated chain of classes

205 views Asked by At

My class A creates in its constructor an instance of class B. Class B's constructor creates an instance of its inner class C. Class C needs a field in its constructor from class A and here is the problem. Class C reaches only the default value of the field of A.

I initialize the value of the field of A in A's constructor before starting the initiation of B and C. I checked that the field has the value I need. Nevertheless, the value of that field in the constructor of C is always the default one. I am not sure how to deal with this. Any help?

Thanks!

Thank you guys for all answers! I felt though that more information is necessary.

This is part of my class A: The problematic variables are startX and startY. I defined them in the constructor either directly, ether through setter method. Class B is DrawView. Class C is DrawThread. I do not know how to pass arguments to the constructor of DrawView, otherwise I would. Help? Another option is to use /*display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();

in DrawView or DrawThread to set my startX and startY, but it just does not want to work. This really switches my question more to android now, and I will be grateful for any suggestions how to get screen size in the constructor of DrawThread, which was the ultimate goal of all that:)?

public class ColorAnimation extends Activity {

    public static float startX;

    public static float startY;

             //other stuff here

             @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // turn off the window's title bar
        requestWindowFeature(Window.FEATURE_NO_TITLE);

        // tell system to use the layout defined in our XML file
        setContentView(R.layout.main);
        /*display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();

        startX = display.getWidth();
        startY = display.getHeight();*/

        mDrawView = (DrawView) findViewById(R.id.pend);
        mDrawThread = mDrawView.getThread();

        // give the DrawView a handle to the TextView used for messages
        mDrawView.setTextView((TextView) findViewById(R.id.text));

Constructor of class B:

//

public DrawView(Context context, AttributeSet attrs) { super(context, attrs);

    // register our interest in hearing about changes to our surface
    SurfaceHolder holder = getHolder();

    holder.addCallback(this);

    thread = new DrawThread(holder, context, new Handler() {

        @Override
        public void handleMessage(Message m) {
            mStatusText.setVisibility(m.getData().getInt("viz"));
            mStatusText.setText(m.getData().getString("text"));
        }
    });

    setFocusable(true); // make sure we get key events
}

//part of class C DrawThread:

class DrawView extends SurfaceView implements SurfaceHolder.Callback {

    class DrawThread extends Thread {//................
         //..............


    public DrawThread(SurfaceHolder surfaceHolder, Context context,
            Handler handler) {
        // get handles to some important objects
        mSurfaceHolder = surfaceHolder;
        mHandler = handler;
        mContext = context; 
3

There are 3 answers

0
Kurtis Nusbaum On

You could create a function in class A that accesses the value of field A. Then just pass the instance of class A all the way down to class C. Without more details, I don't think I can give a more detailed answer.

0
Pedantic On

Until the constructor for class A is completed (which means the constructors for B and C have completed), its best to assume that you don't have access to a fully-constructed and populated instance of A. You should pass down the value you're setting to A.field into the constructor for class B and reference it that way.

5
Nate On

If it's really a class field then it should work. This SSCCE always returns "A SET IT".

class A {

    public static String VALUE = "default";

    public A() {
        VALUE = "A SET IT";
        B b = new B();
    }

}

class B {

    public B() {
        C c = new C();
    }

    public static class C {
        public C() {
            String value = A.VALUE;
            System.out.print(value);
        }
    }
}


public class Runner {
    public static void main(String[] args) {
        A a = new A();
    }
}

If the value you're trying to access is really an object field (i.e. not static), this isn't the case - the object isn't really created until the constructor completes.

There may be other things affecting this in your specific case - classloaders, threads, etc. that you didn't mention.