I have a very weird situation. I have a class that has a couple of members, like this:
public class myMainClass
{
public aClass myObject = new aClass();
private int numberOfUpdates = 0;
public anotheClass.memberClass anotherObject = new anotheClass.memberClass();
Note that the anotherClass has a class defined within it. (Not sure if that enters into the problem I'm having).
Both aClass and anotheClass.memberClass have a member with the same name, ThisMember.
I also have a method within myMainClass that does some modifications to the members of the myMainClass object:
public void Update(double aPassedInNumber)
{
anotherObject.ThisMember = aPassedInNumber;
//etc
}
I'm only modifying that one member. However, when I do that, myObject.ThisMember also gets modified to the same value! It's as though (??) both member variables occupy the same location in memory. Or that one is somehow a reference to the other.
It's as if I had done:
public void Update(double aPassedInNumber)
{
anotherObject.ThisMember = aPassedInNumber;
myObject = aPassedInNumber;
//etc
}
BUT I'M NOT. I'm only doing the first assignment, yet both of those variables get modified.
I've traced this and printed out diagnostics and used a watch window and it clearly modifies both variables.
How can that be? What am I doing wrong? How can I fix it?
Oh, man. It looks like I still don't have a handle on the reference concept in JAVA. That one variable is indeed simply a reference to the other object.
Now it seems I have to implement a copy method for the class.
Aaaargh!!
Related
can you explain me which is the difference between:
public class Test {
public static final Person p;
static {
p = new Person();
p.setName("Josh");
}
}
and
public class Test {
public static final Person p = initPerson();
private static Person initPerson() {
Person p = new Person();
p.setName("Josh");
return p;
}
}
I have always used the second one, but is there any difference with an static initializer block?
There are of course technical differences (you could invoke the static method multiple times within your class if you wanted, you could invoke it via reflection, etc) but, assuming you don't do any of that trickery, you're right -- the two approaches are effectively identical.
I also prefer the method-based approach, since it gives a nice name to the block of code. But it's almost entirely a stylistic approach.
As Marko points out, the method-based approach also serves to separate the two concerns of creating the Person, and assigning it to the static variable. With the static block, those two things are combined, which can hurt readability if the block is non-trivial. But with the method approach, the method is responsible solely for creating the object, and the static variable's initializion is responsible solely for taking that method's result and assigning it to the variable.
Taking this a bit further: if I have two static fields, and one depends on the other, then I'll declare two methods, and have the second method take the first variable as an explicit argument. I like to keep my static initialization methods entirely free of state, which makes it much easier to reason about which one should happen when (and what variables it assumes have already been created).
So, something like:
public class Test {
public static final Person p = initPerson();
public static final String pAddress = lookupAddress(p);
/* implementations of initPerson and lookupAddress omitted */
}
It's very clear from looking at that, that (a) you don't need pAddress to initialize p, and (b) you do need p to initialize lookupAddress. In fact, the compiler would give you a compilation error ("illegal forward reference") if you tried them in reverse order and your static fields were non-final:
public static String pAddress = lookupAddress(p); // ERROR
public static Person p = initPerson();
You would lose that clarity and safety with static blocks. This compiles just fine:
static {
pAddress = p.findAddressSomehow();
p = new Person();
}
... but it'll fail at run time, since at p.findAddressSomehow(), p has its default value of null.
A static method (second example) is executed every time you call it. A static init block (first example) is only called once on initializing the class.
http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html
The advantage of private static methods is that they can be reused later if you need to reinitialize the class variable.
This does not count for final instances, because a final variable can only be initialized once.
initPerson requires calling at some point, whereas the static block is executed when creating the Test object.
The static before a function specifies that you can use that function by calling it on the Class name handle itself. For example, if you want to create a Person object outside the class you can write
Person p = Test.initPerson();
However, there is no advantageous difference between the two as you can access the object p outside the class in both cases.
class A
{
int i = 10;
public static void main(String[] args)
{
A a= new A();
a.i=20;
}
}
is running fine but when try to write following code
class A
{
A a= new A();
int i = 10;
public static void main(String[] args)
{
a.i=20;
}
}
it is giving compile time error. It means that whatever(assume reference variable) we write inside the static method is treated as a static variable implicitly.
You are mixing up class scope, method scope, and instance scope.
First remember that when you have something that is static, it is available to all instances of that class. When something isn't static, it is only available to a specific instance of a class, and is not shared. Because of that, static methods cannot act on instance variables (or methods).
In the first example, you create an A scoped to the main() method. The fact that main() is static has nothing to do with it, this is method-level scoping. When you call .i on that instance of A, you are calling it on the instance local to your scope.
In the second example, you are saying that whenever an A is instantiated, it will have another instance of A within it (which leads to other problems, see below). This is at the object instance scope. When you try to call it from your static-scoped main() method, the compiler has no idea which specific instance of A you want to use. Each one has its own version of i.
And finally, by creating an instance of A within every other instance of A (A a = new A();) your code will never run, you'll get a StackOverflowException.
Edit to answer question:
OK, when you do something like this:
public class Person {
String name = null;
}
You are saying, that for every Person we create (via new), they have a name that is for them, and them only. They don't share it with anybody.
So when you do something like this:
public class A {
A a = new A();
}
You are saying that for every A we create (via new) it has another A that is for that instance and that instance only. See where this is going? You end up infiniately creating A objects until java runs out of room on the stack for them. The first A is created, and tries to create its internal A, which tries to create its internal A and so on and so on.
I have the following, stripped-down Java code:
// Class, in it's own file
import java.util.*;
public class Superclass {
protected List<Subclass> instances = new ArrayList<>();
public class Subclass extends Superclass {
private int someField;
public Subclass(int someValue) {
this.someField = someValue;
updateSuperclass();
}
private void updateSuperclass() {
super.instances.add(this);
}
}
}
// Implementation, somewhere else, everything has been imported properly
Superclass big = new Superclass();
Subclass little1 = big.new Subclass(1);
Subclass little2 = big.new Subclass(2);
Subclass little3 = big.new Subclass(3);
I want to implement a method in Superclass to do something with all the Subclasses. When a Subclass is created, it should add itself to a list in Superclass, but whenever I try to loop through that list in Superclass, it says the size is 1. The first element in the list (instances.get(0)) just spits out a String with all the proper information, but not in object form, and not separately. It's like every time I go to add to the list, it gets appended to the first (or zeroeth) element in String form.
How can I solve this so I can maintain an ArrayList of Subclasses to later loop over and run methods from? I'm definitely a beginner at Java, which doesn't help my case.
If all you need is a count then I suggest a static value that is updated in the constructor of the parent class.
private static int instanceCount = 0;
public Constructor() {
instanceCount++;
}
If you absolutely need every instance in a list so you can do something with them then I recommend you strongly re-consider your design.
You can always create a utility class that will let you maintain the list of objects to run processes on. It's more "Object Oriented" that way. You can also create one class that has all of the operations and then a simpler bean class that has only the data values.
But, if you insist, you can still use the same technique.
private static List<SuperClass> list = new LinkedList<SuperClass>;
public Constructor() {
list.add(this)
}
Each instance gets its own copy of your superclass's variables.
What you want to do is make the variable "static" by putting the static keyword before it. You probably don't even need the superclass accomplish what you're trying to do.
I have a java application that creates two static objects in a base class, these objects needs to references throughout classes in the program.
public class Baseclass{
public static ClassA A = new ClassA();
public static ClassB B = new Classb();
...
...
...
}
These objects are referenced in the other classes as a local private variables.
public class ClassA{
private ClassB b = Baseclass.B;
However, both object require each other to function and if I creates a new instance of one of the objects before the other is created, the local variable in the "upper" classes is set to null. Is there any concepts in Java that would reference the actual object (like a pointer) to the object as a variable instead of making a copy of the object?
However, both object require each other to function and if I creates a new instance of one of the objects before the other is created, the local variable in the "upper" classes is set to null.
I think the answer you are looking for is a "singleton pattern". This is where you create just one instance of a class for use in other places. Here's a good link to read. Here's the wikipedia page on it with some java examples.
So your code would look something like this:
public class A {
private final static A instance = new A();
/* private constructor forces you to use the getInstance() method below */
private A() {}
public static A getInstance() {
return instance;
}
}
Then wherever you want to get an instance of A you would do something like:
public class B {
private final A classA = ClassA.getInstance();
...
}
There is no reason why A could not also have an instance of B and call B's methods in its own methods. What you cannot do with this cross dependency is call any of the other's methods in the constructor.
In general, by the way, these patterns should be used sparingly. A better way to accomplish this is through dependency injection instead of global references. Cross injection is possible but again, it should be used sparingly. A better solution would be to refactor the classes to have linear dependencies.
Is there any concepts in Java that would reference the actual object (like a pointer) to the object as a variable instead of making a copy of the object?
Java is pass by value but the value of any Object is the reference to the object (similar to pointers in C although they are not a memory address). So if you have an instance of A and assign it to another field, that field will be the same value and will be referencing the same instance of A.
// instantiate a new instance of A
A a1 = new A();
// assign the reference to A to another variable
a2 = a1;
// they are equivalent and both reference the same object
if (a1 == a2) ...
Is there any concepts in Java that would reference the actual object (like a pointer) to the object as a variable instead of making a copy of the object?
Actually, Java has only references. A variable can't contain an object, so no worries there.
Also, instead of doing
private ClassB b = Baseclass.B;
I'd suggest you consider doing a static import:
import static some.package.Baseclass.*;
When you make a reference in Java you are actually making a copy of a reference. You aren't copying Baseclass.B in your example. You're copying a reference to Baseclass.B.
In the example code you have provided, b is going to be null until Baseclass.B is defined. If you need to do an operation on b, you can't do it in the declaration of ClassA. You need to do it in a method that is called after object a has been created.
This is a classic application for a singleton.
For each one:
Make the constructor private.
Add a private static member of the class's own type to hold the
singleton.
Add a "getThe()" method which initializes the above member if it's not already set.
See wikipedia:Singleton pattern.
Make the constructor of A construct B also, by doing a getThe() on it.
Also, don't use public fields in Baseclass; instead use public getter methods. Don't keep a separate B variable; instead, ask the A singleton for it.
Is there any concepts in Java that would reference the actual object
(like a pointer) to the object as a variable instead of making a copy
of the object?
When you do this:
private ClassB b = Baseclass.B;
Really you are ponting at the same object a it's because the "b" variable is named Reference Variable.
About your question, my recomendation is do something like this:
First encapsule the reference:
public class ClassA{
private ClassB b;
public void setB(ClassB b) {
this.b = b;
}
public ClassB getB(ClassB b) {
return this.b;
}
}
Second use an static block for init the variables:
public class Baseclass{
public static ClassA A = new ClassA();
public static ClassB B = new Classb();
static {
A.setB(B);
B.setA(A);
}
}
Let's say we have a class like this one:
class XCopy {
public static void main(String[] args) {
int orig = 42;
XCopy x = new XCopy();
int y = x.go(orig);
System.out.println(orig + " " + " y);
}
}
I know the go method is missing but never mind. Should this work? It appears so, but I just can't picture in my head how that self-reference inside the class works; does it have any side effects? Why does this work? Isn't that some sort of infinite recursive loop?
Anyway, I just can't figure out exactly how this works; thanks in advance.
I gather you are looking at this and thinking it is a chicken and the egg type issue, but it's not at all.
If this is your first OO language you are probably confused about Java's terminology. Java has something called "static methods". You're main(String[]) method is a static method. These static methods are really just plain old functions. Object Oriented methods on the other hand are called "instance methods" or just "methods". People are often sloppy about the terminology.
In Java, a function (i.e. static method) must be defined in the same place as a class and uses that classes' name identify it. But, it is still just a plain old function. Sometimes a class just has nothing but a bunch of loosely related functions/static methods. Like the Math class has a bunch of functions about math. Sometime a more OO class like string will have some static methods/functions thrown in with the OO methods.
In your program your main function has nothing to do with your class. But it's still perfectly fine to put it there for a small example.
When Java starts in ALWAYS starts in a main function somewhere (you can tell it what class the main function is in).
So when your program runs the JVM selects your main function as a valid main function. It runs the function. Its just a function it doesn't need any objects. Calling main does not create any objects.
Now, when your are in main(String[]) you happen to create an Object here:
XCopy x = new XCopy();
Now you have a new object of type XCopy pointed to by the reference (object pointer) x in the local scope of the main function. If XCopy had a constructor it would have been called.
So if you want to picture it in your head let me write it in a fictitious language for you that has a clear more visual syntax!
here it is:
Namespace XCopy
{
function void main(String[])
{
int orig = 42;
XCopy x = new XCopy();
int y = x.go(orig);
System.out.println(orig + " " + " y);
}
}
Class XCopy
{
method int go(int i)
{
....
return whatever;
}
}
In this same program in this other languages' syntax you can see that you have one function, one class with one method, and you have one instance of that class.
Hope that helps!!
By calling
XCopy x = new XCopy();
you are actually calling XCopy's empty constructor, not main method again.
So, the calls look like:
JVM calls XCopy.main();
main method creates new instance of XCopy by calling XCopy's empty constructor
XCopy constructor ends
main method ends -> program ends
Why would it recurse? main() isn't called anywhere within itself, so it wouldn't recurse. A class is in scope of its own members, so you can create instances of it.
Take for instance a makeCopy() method; it would need to create an instance of another object of its own type.
Don't think of methods as being "inside" a class/object and the action of calling a method from within itself as anything awkward; a method is just a function with an implicit this parameter.
The main method is static, meaning that its code can be accessed independently of the fact that there is an instance of Xcopy. Hence, there is no conflict or recursive loop. It has its own memory space which is different than the memory space allocated for each class instance.
main() is static, therefore you can consider it part of the class, but not of an instance. It gets called by OS+JVM and creates an instance of a class. That class happens to be the class where main() is defined, but that really doesn't matter.
Imagine a different class:
public class Person {
private String name;
private Person favorite;
public Person(String name) { setName(name); }
public void setFavorite(Person favorite) {this.favorite = favorite;}
public Person getFavorite() { return favorite; }
public void setName(String name) {this.name = name;}
public String getName() { return name; }
public static void main(String args[]) {
Person a = new Person("Alex");
Person b = new Person("Becky");
Person c = new Person("Chris");
Person d = new Person("David");
a.setFavorite(b);
b.setFavorite(c);
c.setFavorite(c);
}
}
So, Alex's favorite person is Becky. Becky's favorite person is Chris. But Chris is a narcissist; his favorite person is himself. David doesn't have a favorite person. Sadly, nobody thinks David is their favorite person.
When you apply the concept of self-references to something with real-world semantics, doesn't it make sense that such a structure is possible? Note, setting a self-reference doesn't create a copy. There is still only one Chris in this program.
As long as you don't make the move of saying, "I'm going to ask each person who their favorite person is. Then I'm going to ask that person who their favorite person is. I'm not going to stop until I find David. Because then, you do have a chance at looping forever.