This question already has answers here:
What is the meaning of "this" in Java?
(22 answers)
Closed 8 years ago.
I'm currently reading about the this keyword and don't understand why is it useful to do things like:
this.object = object;
(object is a random variable. I just don't understand why we do like, this.xxx = xxx)
Help me please!
It's necessary to specify that you want to assign the value to the field, rather than the parameter or local variable:
public void setFoo(Foo foo) {
this.foo = foo;
^ ^
| \--- Take the value of the parameter
\---- Assign to the field
}
If you just wrote:
foo = foo;
in the above, then it wouldn't do anything - it would be assigning the value of the parameter back to the parameter.
Another option, however, is to use a different parameter name instead:
public void setFoo(Foo newFoo) {
foo = newFoo;
}
Now the field and the parameter have different names, so you don't need to find another way to differentiate between them.
imagine having a setter like
private Object obj;
public void setObject (Object obj)
{
this.obj = obj;
}
this this scope the object to the class field otherwise with
obj = obj;
you would be setting the same object to be the same object.
Related
This question already has answers here:
Create instance of generic type in Java?
(29 answers)
Closed 8 years ago.
I'm not certain if this is possible in Java. Also, I'm not able to figure out what to query on Google for this.
Anyway, I want a method that takes as an argument a Class (interface or class) and the method's return type is an instance of that Class. I don't want to have to recast an Object after the fact.
I'm not certain if this feature exists or what the syntax would be. Let's say I have a class named XYZ and here is my pseudo method.
private XYZ createInstance(XYZ.class, other args) {
...
// create an instance of XYZ with other args named "_xyz_"
...
return _xyz_;
}
Now assume XYZ is some sort of generic syntax. Is this possible at all in Java? Thanks for any help.
private <T> T createInstance(Class<? extends T> c) {
return c.newInstance();
}
Use the diamond operator:
private <T> T createInstance(Class<T> concreteClass){
return concreteClass.newInstance();
}
//usage
Integer i = instanceWithThatMethod.createInstance(Integer.class);
To pass "arguments", you have to get the Constructor of the class matching the desired parameter types, and invoke the call on that one, like this:
private <T> T createInstance(Class<T> concreteClass, String stringArg){
return concreteClass.getConstructor(String.class).newInstance(stringArg);
}
//usage
SomeClass s = createInstance(SomeClass, "testString");
//equals
SomeClass s = new SomeClass("testString");
//where SomeClass HAS to serve:
public SomeClass(String s){
...
}
This question already has answers here:
Is there a way to instantiate a class by name in Java?
(9 answers)
Closed 8 years ago.
Is it possible in Java to use variables value for type?
For example:
String s = "String";
And then I would create another variable z, which could use s value for his type. Is it possible to do that? Maybe with reflection or some other technique?
Update:
If it's not possible this way, maybe someone could suggest how to give type to variable, when you get what type it is from xml files attribute? Like
<tag type="String">MyValue</tag>
And then I could use type attributes value for defining variables type?
Do you look for something like this:
public static void main(String[] args) {
String s = "java.lang.String";
Object o = "Some Value";
Class<?> type;
try {
type = Class.forName(s);
getValue(type, o);
} catch (ClassNotFoundException e) {
// class was not found
e.printStackTrace();
}
}
private static <T> T getValue(Class<T> desiredType, Object o) {
if (o.getClass().isAssignableFrom(desiredType)) {
return desiredType.cast(o);
} else {
throw new IllegalArgumentException();
}
}
I know no language allowing it the way you wrote, and about other ways: you could achieve it with typedef in C or C++, but not in Java. However, you could often extend a class like this:
public class myName extends originalClassName {}
and then use myName instead of originalClassName. However, you can not do this with String, which is final and therefore can't be inherited after.
This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 9 years ago.
Code:
class AB{
int i=5;
}
class BC{
public void test(AB a){
a.i=10;
}
}
public class ATest{
public static void main(String aa[]){
AB a = new AB();
//Base class variable value
System.out.println(a.i);
BC b = new BC();
//Modifying the object "a"
b.test(a);
//Printing the base class object
System.out.println(a.i);
}
}
// Output : 5
// 10
If it is pass-by-value, the output should have been 5 and 5
Java uses pass-by-value but if the parameter is an object Java passes by value the reference to the object, so the called method can change the content of the object, not the object as a whole.
This does not mean that objects are passed by reference (the comment by Joachim Isaksson is wrong).
ADDED to answer to the comment by Arijeet Saha:
When I say "the called method can change the content of the object, not the object as a whole", I mean that if you change the object as a whole the caller doesn't see the change.
Consider the following example:
public void test(Person p) {
p.setName("Pino");
p = new Person();
p.setName("John");
}
The first line of test() changes the content of the object received by the method, the second line changes the object as a whole (it assigns a new object to the formal parameter), the third line changes the content of the new object. In this case the caller sees a Person object with name "Pino", not "John", because the change made by the second line of test() is not visible to the caller; it is not visible because objects are not passed by reference.
Let me first clear what does pass-by-value mean?
It means what ever you are passing to a method, it will recieve its copy not the actual adress.
So in your case you too are passing the value the variable a, and its value (which is referance to an object or adress to an object) is copied to the method(AB a).
Java's parameter passing is quite tricky - When an object is passed to a function, you can manipulate the object's fields but you cannot manipulate object itself. The object reference is passed by value. So, you can say:
class someClass{
int i = 5;
}
class Foo
{
static void func(someClass c)
{
c.i = 3;
}
}
class MainClass{
public static void main(){
someClass c = new someClass();
System.out.println(c.i);
Foo.func(c);
System.out.println(c.i);
}
}
Expect your output to be:
5
3
Changes to the fields of c persist.
but if manipulate the object itself, this manipulation will only persist in Foo.func() and not outside that function:
class someClass{
int i = 5;
}
class Foo
{
static void func(someClass c)
{
c.i = new someClass();
c.i = 3;
System.out.println(c.i);
}
}
class MainClass{
public static void main(){
someClass c = new someClass();
System.out.println(c.i);
Foo.func(c);
System.out.println(c.i);
}
}
Expect your output to be:
5
3
5
What has happened? c.i has the value 5 in MainClass.main() in Foo.func(), c itself is modified to point to another instance of someClass, containing the value 3. However, this change is not reflected to the actual object that has been passed. The c in Foo.func() and MainClass.main() are different objects now. That's why changes to the c of Foo.func() do not affect the c in MainClass.main().
Java always passes parameters as by value.
It's important to understand what is the value (what a variable holds).
For primitives it's the value itself.
For objects it's a reference.
When you pass an object as a parameter - the reference to the object is copied but it still points to the original object.
This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
passing by reference in Java doubts
(5 answers)
Closed 8 years ago.
If I have a class like the one below:
public class Foo()
{
private RandomObject randomObject = new RandomObject();
public RandomObject GetRandromObject()
{
return randomObject;
}
}
And in another class I do this:
public class Goo()
{
private Foo fooObject = new Foo();
public Goo()
{
RandomObject ro = fooObject.GetRandomObject();
ro.ChangeNumberVariable(23);
}
}
Will the fooObject have the randomObject NumberVariable changed to 23?
If not would I just have to have a method in Foo called SetRandomObject and just pass in ro? Would this be a good substitute for passing by reference in Java?
What if I just did this:
public class Goo()
{
private Foo fooObject = new Foo();
public Goo()
{
fooObject.GetRandomObject().ChangeNumberVarialbe(23);
}
}
Is it still not changing the NumberVariable?
In both cases fooObject.randomObject would have NumberVariable changed to 23. They are pretty much equivalent just the former uses an extra reference.
This does not make Java pass-by-reference. Java is pass by value. Any time you pass something to a method as a parameter it is copied, even if what you pass is a reference to an object.
Though you can use that copied reference to access and mutate the object on the end of it, as you are doing here, any re-assignment of that reference cannot escape the method.
In your first example doing:
ro = new RandomObject();
would not change anything about fooObject.randomObject.
How do I create a reference to a constant object?
final Myclass obj = new Myclass();
does not work, it says obj(the reference) should not be re-assigned but we can still change the object referred. I want to ensure that the object itself does not change once constructed.
Just make it immutable (like String is). Or wrap it in another object which restricts access to mutators of the object in question (like Collections.unmodifiableList() and consorts do).
You are mixing two things: final and immutable.
A variable can be final, so you can't change it's a value (or object reference) after it is initialized (but of course you can change the reference's objects attributes)
An object can be immutable (not a keyword but a property), so you can't change it's value after it is created. The string is a good example - you can not change the backing char[] inside a String object.
What you want is an Immutable Object. There are no keywords in Java that can instantly make an object immutable. You have to design the object's logic, so that its state cannot be changed. As BalusC put, you can wrap it in another object which restricts access to its mutators.
I don't think there's any built in keyword to make that possible in Java. Even if the reference is constant/final, the internals of the object could still be changed.
Your best options is to have a ReadOnly implementation version of your class.
You can read more about this here: http://en.wikipedia.org/wiki/Const-correctness#final_in_Java
In Java, an immutable class is generally means that it doesn't have "setters" and any field that can be accessed with a "getter" should also be immutable. In order to get your data into the class to start, you'll need to have a constructor that takes the values as arguments:
public class MyClass {
String something;
int somethingElse;
// The class can only be modified by the constructor
public MyClass(String something, int somethingElse) {
this.something = something;
this.somethingElse = somethingElse;
}
// Access "something". Note that it is a String, which is immutable.
public String getSomething() {
return something;
}
// Access "somethingElse". Note that it is an int, which is immutable.
public int getSomethingElse() {
return somethingElse;
}
}
Yes it does you seem to have forgotten to set the type.
final MyClass obj = new Myclass();
That means that obj can only be assigned once. Java does not have a const keyword like C++ does. If MyClass is not declared final (final class MyClass { ... }) it can still change.
final variables should be assigned in the moment of declaration.
final MyClass obj = new MyClass();
In java object constant means you cannot change its reference but you can change the values of its state variables untill they are not final. if all the member variables are final then its a perfect constant, where you cannot change anything.
Here is a way to wrap any object to make it "roughly" immutable.
All method calls that are not 'getters' will throw an Exception. This code defines a getter as a method that meets these criteria:
name of the method starts with get or is
it takes no arguments
it returns a value (not void return type)
Yes, getter methods could mutate an object. But if your code (or code you are using) is doing that, you have some bigger problems, please go get some help :)
the code:
class ImmutableWrapper
public static <T> T wrap(T thing) {
return (T) Proxy.newProxyInstance(thing.getClass().getClassLoader(), new Class[]{thing.getClass()}, OnlyGettersInvocationHandler.instance);
}
private static class OnlyGettersInvocationHandler implements InvocationHandler {
public static InvocationHandler instance;
#Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
final String name = method.getName();
if ((args == null || args.length == 0)
&& (name.startsWith("get") || name.startsWith("is")
&& !method.getReturnType().equals(Void.class))) {
return method.invoke(proxy, args);
} else {
throw new UnsupportedOperationException("immutable object: " + proxy + ", cannot call " + name);
}
}
}
}
SomeClass myThing = ... create and populate some object ...
SomeClass myImmutableThing = ImmutableWrapper.wrap(myThing);
myImmutableThing.setValue('foo'); // throws Exception
myImmutableThing.whatever(); // throws Exception
myImmutableThing.getSomething(); // returns something
myImmutableThing.isHappy(); // returns something
Mayby you can create class with final attributes. So, you can't change it: object == const.
At least "String" immutable because of it:
public final class String implements Serializable, Comparable<String>, CharSequence {
private final char[] value;
//...
}