views:

302

answers:

6
class MetaData {
    public String version;
    public String compression;
}

I make a MetaData object, pass it into a method, and fill the version and compression fields from within the method. And I want these changes to exist outside of the lifetime of the method. In C++ I think I added a & or something to pass the object itself and not a copy of it to the method. Is there ANYWAY to do the same in Java?

A: 

Use arrays:

void myMethod(MetaData[] args)
{
    args[0]. version = "some";
    args[0]. compression = "some";
}
Dewfy
How does using arrays help?
Amuck
array is passed by reference, as you expects in C++
Dewfy
every object in java is passed by reference.
Nico
+17  A: 

This will always happen in Java. It's just the way Java works. When you pass a "MetaData" object to a method, a reference to that object is passed and any modifications made to its "version" and "compression" fields should be seen everywhere.

Check out this article for a really in-depth explanation:

http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html

Brent Nash
+4  A: 

Java has pass by value semantics. This does not mean that objects are passed by value to methods. Rather, it means that references to objects are passed by value to methods.

So in this scenario, when you create a MetaData object, and pass it to a method where in the fields are populated, the reference to the object is passed to that method. Once the method returns, you can examine the object reference in the caller to confirm that its fields have been set.

By the way, this is a bad practice in OOP, if you are sending a MetaData object to another class for setting the state of the object. Objects themselves should be in charge of their state.

Vineet Reynolds
+4  A: 

This is the default behaviour in Java.

class Example {
   public static void doit(MetaData data) {
     data.compression = "Testing"
   }

   public static void main(String[] args) {
     MetaData data = new MetaData();
     doit(data);
     System.out.println(data.compression);
   }
}
Allain Lalonde
+1  A: 

All mutable objects you pass to methods can be changed, and the original will change. The problem is that String cannot be changed--it is immutable.

Pass an object that can be changed.

If you want to change "version", then give your class "MetaData" a .setVersion() method and pass "MetaData" to your method. Your method would call metaData.setVersion("I'm NEW"); and everyone will be happy.

public void willWorkFine (Metadata metaData) {
    metaData.setVersion("Changed!");
}

What you can't do is pass "version" to a method expecting a String and re-assign it:

public void wontWork(String changeMe) {
    changeMe="not changed!";
}

Since changeMe is just a local reference to the original "version" object, reassigning your local reference to point to a different object has no effect on the outside program.

Bill K
A: 

You may add a wrapper like this. So your class would be:

class MetaData {
    public _<String> version;
    public _<String> compression;
}

And use it the way you want it:

class AnyOther {
     public void instantiate()  {

           MetaData m = new Metadata();

           m.version = new _<String>("v1.0");
           m.compression = new _<String>("compression");

           _<String> currentVersion = m.version;

           System.out.println( "Before: " + currentVersion );

           changeIt( m );

           System.out.println( "After: " + currentVersion );


     }

     private void changeIt( MetaData m ) {
        _<String> currentVersion = m.version;

       currentVersion.s("1.1");

    }
}

Should print

  Before: 1.0
  After: 1.1

But, I think it is a bit awkward.

If your are programming in Java you may consider leave the responsibility of that value to the holding class "MetaData" rather and stripping away its attributes.

class AnyOtherJavaWay {
     public void instantiate()  {

           MetaData m = new Metadata();

           m.version = "v1.0";
           m.compression = "compression";

           String currentVersion = m.version;

           System.out.println( "Before: " + currentVersion );

           changeIt( m );
           // you have to get it again...
           currentVersion = m.version;  

           System.out.println( "After: " + currentVersion );


     }

     private void changeIt( MetaData m ) {
         // let the objet "m", hold the new value
         // it is his ( its'??? ) responsability
         m.version = "1.1";
    }
}

Which yields the same result.

OscarRyz