• Post Reply Bookmark Topic Watch Topic
  • New Topic

References between classes  RSS feed

 
Dunc Smith
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi
I can't see what is wrong in the following situation. I am just trying to access an instance variable in one class, "First" from another, called "Second", where Second happens to be itself instanciated in First. This appears to follow the guidance on http://download.oracle.com/javase/tutorial/java/javaOO/classvars.html

I've simplified the code I was working on to the bare minimum that replicates the error. The symptom is that the Second class won't compile with the following error
"cannot find symbol
symbol : variable f
location: class Second
System.out.println(f.dummy);"


Here is the code for the two classes



and



It doesn't seem to matter that I have completely defined "dummy" in the header, I'd get the same result if it is assigned in a constructor within First. I get the same compile error if I place both First and Second in the same package and also if I go to the lengths of defining a "get" method in First to access the value.

Many thanks for any pointers!
Duncan
 
Paul Clapham
Sheriff
Posts: 22832
43
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The message says that it can't find something named "f". Given that, the fact that something called "dummy" exists is somewhat irrelevant. Concentrate on the message: the "Second" class doesn't have a field named "f".
 
Daniel Marti
Ranch Hand
Posts: 37
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The message tells you that Second cannot find f (disregard the rest of it).
Knowing that, what do you think is wrong in your code?
I'll point out that if A instantiates B, A knows B (with heavy restrictions depending where you instantiated it), but do you think B will know A?

Edit: Beaten by Paul Clapham...
 
Dunc Smith
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi
Thanks both of you for being gentle with me though I'm still struggling. Your main point is, I think, that there are no other references in Second to f or First. This has puzzled me as to how to interpret the reference material (I realise now I should have linked to http://download.oracle.com/javase/tutorial/java/javaOO/summaryclasses.html ) - this appears to imply that no further reference is necessary, as objectReference.variableName is cited there.

1. I don't think you are asking me to define
First f; in the constructor of Second, which doesn't compile, nor
First f;
or
First f = new First();
in the header area before the constructor, both of which interestingly compile and produce run time errors.

2. As an aside I can also see that if I change dummy to be a static variable (and if I correspondingly change the reference in Second to First.dummy) then it compiles and runs, but the whole point is that I want to reference an instance variable, not a class variable.

3. I can see now that I've made another error in that I've not made dummy public, but as Paul says this seems irrelevant as it is the instance f of First that the compiler has given up on.

4. Also, and you can see I'm guessing now, it doesn't appear to help to move the instantiation of "s" to the main block.

I think the question I am having trouble with is that if this simple example will not compile because of the apparently obvious reason that First is not visible from Second then I can't see how to generalise so that any class can access any instance variable of another.

Any next clues much appreciated!
 
Daniel Marti
Ranch Hand
Posts: 37
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
As a preliminary reading, please check "Variable Scope" in your favorite tutorial/book.

Done that? Now into the extra clues:
You declare f inside main. Think: what is the scope of f? Is it accessible throughout the package? Only on the First.class? Only on main method? See where it was declared and see what is the scope of f.

Then you declare Second s inside First constructor. Go down to the constructor of Second. What can the constructor access? It can see everything inside it, and also everything inside the class Second. But can it see what is in the main method?

After reading the section i mentioned above, and after following the hints, you should understand why you can't access that f. If you don't, post back.
In case you're wondering why i don't give you a straight answer: if i do, you will 'think' you understand it, but most likely will have similar doubts in the future. If you find out by yourself you can be sure you will never forget what variable scope is, and how to solve related problems.
 
Paul Clapham
Sheriff
Posts: 22832
43
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
But notice that the error message is about class Second. You are spending a lot of time looking at the class First -- but why? The error message is about class Second. Whatever is in First is irrelevant to the error message.

Now focus. Look at class Second. It refers to a variable named "f". So where is the declaration of that variable? No, stop looking in class First. That's irrelevant. Look in class Second. Where is there a declaration for variable "f"?

If you look only at class Second it's crystal clear that it doesn't have any such declaration. So let's add one. What type should it be? Well, from your other code we know you meant it to be of type First, so let's put a variable named "f" of that type into Second:

Here I chose to make it a local variable. Now if I'm not mistaken this code should compile error-free.
 
Harnoor Singh
Ranch Hand
Posts: 35
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Paul,

Though above solution provided will compile but it will give runtime exception. We are creating the object of second class in first class constructor and creating first class object in the second class constructor. We will not be able to create objects because of interdependies of these two classes on each other. Please correct me if wrong.
 
Abhay Agarwal
Ranch Hand
Posts: 1376
Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
@paul -- above mentioned code posted by you , will create stack overflow error as a cyclic dependency got created between First and Second object creation process.

@ duncan -- Welcome to JavaRanch
you can use instance variables of one class in another class and there are various ways to do it.
main problem here is that you are trying to use an instance variable of an object before even that object is fully constructed.
you have called Second object instantiation (new Second()) from First class constructor. now even before Second class constructor execution is over, you are trying to access First class' variable(dummy). After Second class object creation is complete, then only First class object creation will get completed

Refer to this article for more details - http://www.artima.com/designtechniques/initializationP.html

~ abhay
 
Dunc Smith
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi
Thanks everyone for the thought provoking contributions, after much reading and some trying things out the penny has dropped, or at least I hope it has.

@Daniel
After thinking about scope for a bit I think I can understand the point that the constructor in Second has no visibility of what happens in the main method of First. Similarly, if there was to be a third class, instantiated from Second, I could make Second visible to First and Third visible to Second etc but not a specific instance of Third (created in second) visible to First.

@Paul / Harnoor / Abhay
So this circular example is one that I had considered but as you say it leads to runtime exceptions. However in taking up the spirit of the suggestion I considered passing "dummy" into Second as an argument to its constructor.
Interestingly, this appears to work if Second s = new Second is invoked either
- from the constructor for First
or
- from the main method

@Abhay
Thanks for the link, I'm still wading through it. I can at least see the point you are making that it seems to be asking for trouble to access an instance of a First field before its constructor is finished, though the example I just mentioned of passing a copy as an argument of the Second constructor seems to have worked in this case.

Many thanks
Duncan
 
Paul Clapham
Sheriff
Posts: 22832
43
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Harnoor Singh wrote:Hi Paul,

Though above solution provided will compile but it will give runtime exception. We are creating the object of second class in first class constructor and creating first class object in the second class constructor. We will not be able to create objects because of interdependies of these two classes on each other. Please correct me if wrong.


No, you are right. But my goal was only to illustrate the problem. I certainly had no interest in making that example runnable.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!