if java is always pass variables by reference, why does eclipse generate the bean with out any consideration.
instead of:
return myStr;
needs to be
return new String(myStr);
no?
Edit
Ok, my example was bad.
lets leave eclipse, When I want to return a Custom object. Do i need to create a "copy constructor" and return it, like that:
return new MyCustomObject(myCustomObject);
class MyCustomObject{
private String str;
public MyCustomObject(String str){
this.str = str;
}
public MyCustomObject(MyCustomObject obj){
this.str = obj.str;
}
}
Must I write that?
No.
In Java, every object variable is a reference. Objects cannot be passed by value, only primitives can (and always are). Well, that's slightly misleading. The reference is passed by value, but you can think of everything being a reference, just not in a C++ sense.
Perhaps it's easiest to use an example.
SomeObject foo;
public void doSomething(SomeObject bar) {
bar.whatever();
bar = new SomeObject();
bar.someOtherMethod();
}
public void doStuff() {
foo = new SomeObject();
doSomething(foo);
}
So, foo is a reference to an instance of SomeObject. When doSomething is called, the value of that reference is copied to bar, so now foo and bar are references to the same SomeObject.
The line bar.whatever() calls whatever on the same object that foo refers to.
bar = new SomeObject() means that foo and bar now refer to different SomeObject instances, so someOtherMethod is not called on the object that foo refers to.
This is completely different to C++, where
void doSomething(SomeObject& bar) {
bar = whatever;
}
has a totally different meaning. You really should not ever think of Java in C++ terms.
Regarding your example, Strings are immutable in Java so it wouldn't matter even if objects could be passed by value.
Regarding your second example, if you want to return an object that the caller cannot use to pollute your internal state then, yes, you need to have a copy constructor (or something equivalent).
For example:
class ClassWithInternalList {
private List<String> reallyImportantData;
public List<String> getImmutableViewOfData() {
// Take advantage of the java.util.Collections tool for making a List immutable.
return Collections.unmodifiableList(reallyImportantData);
}
public List<String> getSafeCopyOfData() {
// Return a copy that the caller can modify without changing reallyImportantData.
return new ArrayList<String>(reallyImportantData);
}
public List<String> justGetTheData() {
// Return a reference to reallyImportantData that the caller can modify at will.
return reallyImportantData;
}
}
You can choose the appropriate type of return value (normal reference, immutable view or copy) depending on the situation. Any or all of the three options could be appropriate depending on exactly what you are doing.
java.util.Collections makes it easy to get an immutable view of a Collection, but for custom classes you'll need to do your own immutable-ness.
Remember that you only need to do this if there is an issue with mutability. Your MyCustomObject example is still immutable (since the caller cannot change any state in the returned MyCustomObject instance), so the question is still kinda moot.
If the variable is primitive or immutable,you modify what returned won't influence the original property.
Other condition, the variable is a custom type,maybe your class defines a constructor with itself like String,maybe not . So eclipse does not know how to generate it's copy.
As all knows,java pass reference,so java programmers are used to return the reference and allow other modify.Eclipse implement it as default.
If you don't like it ,you can return a copy or implements Immutable.
You usually do not want to create a new object when using getter. What you usually want is to get the reference to object's attribute to work with it easier, for encapsulation and to have the right value even when something else changes the value of the attribute before you use it.
Creating a new instance of an object by method which is called often, is not expected to do it and even does not declare doing such thing is freaking anti-pattern.
Related
I have some closed component which is working over some XML object. I need to expose this object outside of this component, but I don't want to allow changes on it outside of my component. How can I complete this?
Ensure your object has a copy constructor that allows you to make a deeply-cloned copy of your class.
Then call this when you return the object, e.g.
SomeClass instance = // ....
public SomeClass getInstance() {
return new SomeClass(instance);
}
This won't make the returned object immutable. But it doesn't need to be - you just don't want the external code making changes to your copy of the data.
Well, here is the access level's advocate ;-)
If you just wish to prevent the caller from making changes, it doesn't mean that it has to be immutable [in your package] - it just means that it shouldn't have a [public] way to mutate it :) I'm actually a growing fan of returning a limiting public interface.
For instance:
// Option A with a "limiting public interface"
public interface Awesome {
public String getText();
}
class MyAwesome implements Awesome {
public String getText() {
// ..
}
// Option B is to make setText non-public
public void setText() {
// ..
}
}
Then your code can return Awesome which doesn't [directly] provide a way mutate the object.
I think you need to create another class which is immutable, taking your object as a parameter (maybe in constructor). Then you should only expose the instance of your new class.
Here's some tips to make an object immutable: Immutable class?
So I have a simple programming question that I can't seem to find the answer for. While browsing some code from Google I noticed that they put 'this' in front of a lot of methods in their code. What is the purpose of doing this? Does it have any benefits over not using it?
An example:
this.doMethod();
Compared to:
doMethod();
I'm sure its a simple answer, I just like being able to understand all of the code that I read.
No, it makes no difference at all for method calls. Use whichever you find more readable.
Note that it does make a difference when disambiguating between instance variables and parameters (or other local variables though). For example:
public void setFoo(int foo) {
this.foo = foo;
}
That's assigning the instance variable a value from the parameter - just using foo = foo; would be a no-op.
this represents the object instance of the current class. In programming practice, most of the time, it is used to break the ambiguity. e.g. in example, there is a class variable named name and method parameter named named, so this is used to differentiate the two.
public void setName(String name){
this.name= name;
}
If you don't have any ambiguity then it doesn't create much difference i.e. setName("John"); and this.setName("John"); is same thing. But still there is one difference. this.setName("John"); follows the same pattern as you are calling the method on objects(e.g. emp.setName("A");); here this representing the sane class object.
There is no difference between them at all. You always call a method on some reference. If you don't use any reference, this reference is implicit.
So, doMethod() is same as this.doMethod(). By using this, you just make it explicit.
One place where it is required to use this reference explicitly is the place where you are assigning the value of method/constructor parameter to the instance variable, and both have same name, as in the below example:
public Demo(int var) { // Constructor
this.var = var;
}
So, in the above example, this.var refers to instance variable and is different from var, which refers to constructor parameter.
Eclipse will give an error, "The left-hand side of an assignment must be a variable", when I try something like:
public class Thing{
String a1;
int a2;
public void meth(){
Thing A = new Thing();
this = A;
}
}
I had to assign each variable (this.a1 = A.a1; this.a2 = A.a2;) as a work around.
Are there other ways to do this without going through each variable field?
And if this is not a variable what is it called?
this is a pseudo-variable that points to the current instance of the object, it can not be reassigned. It's also considered a keyword in the language, according to section §3.9 of the Java Language Specification.
No, there is no easy shortcut.
And if "this" is not a variable what is it called?
this is not a variable, it's a keyword.
Even though this is special, in many respects it acts like a reference. Therefore, for consistency, this = A would have to be a reference assignment, which doesn't quite make sense.
You seem to be expecting this = A to perform a field-by-field copy from A to this, and indeed Java's designers could choose do that in this case. However, this would be inconsistent with other reference assignments, and the overall benefits of having this as an exception are not at all clear.
this refers to this instance of the class.
You cannot assign to this
this is a java reserved keyword which refers to the current object. its not a variable its a java reserved keyword.
so this = A; is invalid. using this keyword we can refer to any instance variable or method of the current object. you have to refer to the instance variable like:
this.a1 = A.a1;
From Doc:
The most common reason for using the this keyword is because a field
is shadowed by a method or constructor parameter.
You can't assign to this in Java. It's not a variable; it's a keyword.
One thing you might consider, if you don't need a particular instance, is just returning your new instance.
public class Thing{
String a1;
int a2;
public Thing meth(){
Thing A = new Thing();
return A;
}
}
and you'd use it like
whatever = whatever.meth();
According to java lang spec §15.8.3 this is a keyword that is either an expression or statement
When used as a primary expression this denotes a value that is a reference to the object for which the instance method was invoked.
Expression: Something which evaluates to a value. Example: x++
The keyword this is also used in a special explicit constructor invocation statement
Statement: Syntactic elements that control the execution of a program, which are executed for their effect and do not have values Example: if (true)
In either case it is not a variable
Variable: A storage location with an associated type
In your case this is an expression and not a variable. But for all intents an purposes just call it a keyword
Keyword: A character sequence, formed from ASCII letters, are reserved for use ... that cannot be used as a variable name
this refers to the owner of the method.
In this case, the owner is the object itself.
Sometime, this may not refer to the class that you are writing code. Such as in the annoymous class. A common example is the anonymous listener.
button.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
this; // refers to the ActionListener
}
}
);
In addition, you can return this can do method chaining. Supposed you have a class called Homework and it has a method addTask.
public Homework addTask(String task){
return this;
}
you can call the addTask method like
homework.addTask("a").addTask("b").addTask("c");
I think the OP is asking for the ability to assign the contents of one object to another, rather than to assign a new value to the "this" pointer. C++ has this ability -- you can override the assignment operator -- but Java has no such ability.
It would be a nice feature to have in some occasional cases, but it's simply not currently possible, and it doesn't really fit the Java "mold" to provide the function in the future.
The capability would be more useful (and there would be more motivation to provide it) if Java allowed objects to be embedded in other objects (vs simply embedding referenced), but that's not in the cards either.
There is no1 way to copy the values of all fields from one instance onto another in the basic Java language. And you should typically not need it. You can most often just replace the reference to the new instance or work directly on the target instance.
In your case when you want to reset all fields of a object to the initial values (and there is seldomly a need for it) you typically use a reset method which eighter works on its own instance or is a static one working on any given object.
So
class A {
String a1; int a2;
void reset() { a1 = ""; a2 = 0; }
}
would be used as
A a = new A();
// modify a
a.reset();
and
class A {
String a1; int a2;
static void reset(A anotherA) { anotherA.a1 = ""; anotherA.a2 = 0; }
}
and use it like:
A.reset(a);
In both cases it makes sense to use the reset method also for setting the initial values in the constructor: A() { A.reset(this); } or A() { this.reset(); }
1 actually there are some libraries to do it, and you can code it with the help of reflection, the only reason I see it is used is to implement a clone() method or for some kind of wrapping/stubbing.
It sounds to me like what you're trying to do is have a method that reinitializes your object, i.e., set's it back to it's initial values. That's why you want to create a new object, and assign it to the current object, right?
If that's the case, let's try a different way of doing it, since, as has been said, you can't reassign this.
What if, instead of doing that, you tried something like this:
public class Thing {
String a1;
int a2;
public Thing() {
this.meth();
}
public void meth() {
this.a1 = "a1";
this.a2 = 2;
}
}
This way, Thing.meth() actually initializes your object, and the constructor calls it when the object is created. Then you can call it again whenever you'd like.
==Disclaimer, I don't know java==
You would want to assign manually.
I'm not sure why you are trying to create a new instance of Thing inside Thing, but as you don't set the values of a1 and a2 you would need to assign them the way you did.
this is a reserved keyword pointing the class object it is inside.
For example, if you wanted to have another function named fish() your code may look something like this.
public class Thing{
String a1;
int a2;
public Thing meth(){
Thing A = new Thing();
return A;
}
public Thing fish(){
this.a1 = "foo";
this.meth();
return A;
}
}
When you do this = stuff; you are trying to replace the current object instance reference (in this case, the one that you are initializing in the constructor) with another thing, and (in the particular case of java) thats illegal and the language forbids you of doing it.
Think about it, if you could replace the reference to your current instance just like that, then you could incur in some serious memory and security problems (the reference to the constructed object will be lost and overrided by some unknown object).
What is totally valid is referencing members of your current object using the . operator, because they are owned by this, so no problems should arise (at least not evident ones).
The JVM has some inner security measures (e.g., method max stack size verification, class file format validation, etc) that prevents from easy binary manipulation and are enforced by the language syntax. This could be seen as one of those.
I am parsing an XML file where one of the fields I want to be immutable, ID, has to be set after the object is created. Should I set it to null, and throw an exception in the setID() method if ID!=null ?
Edit:
I am parsing an XML file, and at the beginning, I create an object whose fields and objects are populated using information in XML file. I want to be able to set ID, which should be immutable, after creating the root object.
Edit: changed "final" to "immutable" because that's really what I meant semantically. (Sorry :( )
The most common way around this is to use the builder pattern. You build up an object using setters and then once it's ready you create the immutable object using the builder as a template.
You cannot change a final member outside of a constructor. You will have to make it not final.
A better approach might be to use a Builder, as described in Effective Java 2nd Edition in Item 2.
The basic idea is to have a Builder class that has setters (but usually not getters) for the different constructor parameters. There's also a build() method. The Builder class is often a (static) nested class of the class that it's used to build. The outer class's constructor is often private.
The end result looks something like:
public class Foo {
public static class Builder {
public Foo build() {
return new Foo(this);
}
public Builder setId(int id) {
this.id = id;
return this;
}
// you can set defaults for these here
private int id;
}
public static Builder builder() {
return new Builder();
}
private Foo(Builder builder) {
id = builder.id;
}
private final int id;
// The rest of Foo goes here...
}
To create an instance of Foo you then write something like:
Foo foo = Foo.builder()
.setId(id)
.build();
You can also split this up, of course:
// I don't know the ID yet, but I want a place to store it.
Foo.Builder fooBuilder = Foo.builder();
...
// Now I know the ID:.
fooBuilder.setId(id);
...
// Now I'm done and want an immutable Foo.
Foo foo = fooBuilder.build();
You can have multiple setters on the builder, and even add additional parameters to build() or the Builder's constructor.
This lets you have a mutable object while parsing, but switch to an immutable object when you're finished. Your API only ever need expose the immutable object in many cases.
Final fields, by definition, do not change after construction of the object.
If what you really mean is that you want the field to be set once, then you could simply initialize the field to null have the setter for that field throw an exception if the field is no longer null.
You definitely cannot make it final. Throwing an exception from setID() if ID != null is a good idea. Maybe if you provide some more details, someone can come up with a more creative solution?
The field cannot be declared final unless it is initialized during construction. I think something like this might meet your requirements.
class Foo {
private Bar x;
void setX(Bar x) {
if (x == null)
throw new IllegalArgumentException();
if (this.x != null)
throw new IllegalStateException();
this.x = x;
}
}
This Foo implementation is intended for access by a single thread. For multi-thread access, you could use an AtomicReference or externally synchronize access.
Also note that if null is a valid value for x, you can create a private, dummy Bar instance and use it in place of null.
Maybe this nice lib will help you whith parsing xml XStream, so you don't have to bother about object creation. I don't know if you can configure it the way you want, but im sure its worth a look.
I would try to aviod a public setId method, since you get rid of this problem, if you don't have one which some client could call. Try to use the language to tell the user what he can do and what he should not.
If you don't store the id in the xml file you should use a factory which creates the object and uses a parameterized constructor.
If you don't provide a setter for the id, users can only "set" a id when creating the object, and I think thats what you want.
Technically if you can change the value after executing the constructor, it is not "immutable". It's more "semimutable".
But terminology aside: The first idea that occurs to me is to have a "validate" function of some sort. Go through all your setters, and when you think you're done, call validate. If it fails, the object is missing required fields or whatever.
The idea of a builder object is good too. I've never used that pattern. 'Have to think through the pros and cons.
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?
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
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.
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);
}
}
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.