Do something when a variable is (re)assigned Java - java

This is a far-fetched question and I am not sure how to approach this problem, so I am open to other workarounds or proposals. As far as I am aware, what I am trying to do is impossible, but I'd like a second input.
Assume we have the following Java code:
int val = 4;
I am curious as to if some sort of function is called when this statement is executed. An overridable function that assigns a given memory location to this value, or something of that nature.
My objective would be to override that function and store this data here and in a file elsewhere as well.
This would need to work for all data types and for reassignments such as that shown below.
val = getNumber(); // Returns 6;
I would have some sort of direction if I was working with Python, but unfortunately, that is not the case.
My best idea for a solution is to call a function that simply returns a provided argument. Due to the application of this, I'd like to avoid this and keep the usage of this framework as conventional as possible.
Thanks!

I don't think any kind of function happens when we assign values. However when we assign a value to a primitive type(int, double...) variable the value is stored in the stack memory. If the data is reference type (String...), then it is stored in the heap memory. Only the reference address will be stored in the stack. Whenever you decide to change the state of that particular variable (field value) the new value will be stored in the stack overriding the previous value. So, you don't have to worry about methods to override using a method.
If you want to deny access to a variable outside the class, but still change the state of that variable, then you can use encapsulation concept of OOP in java.
For further clarification refer this article about stack vs. heap

Related

How to invoke method of an object whose reference id is stored in String? [duplicate]

My question is relate to security level of JVM
How we can we get the object from memory by proving hash code?
Today i was thinking. I create an object of class A in an execution environment One. And get the hash code from here of that object.
Now in another execution environment i want to get back class A object by providing hash code.
I think it is possible. Because when I execute environment one. Again and again i get that JVM return the same hash code.
Means it first find the object in its cache. If it get the reference, it just return it.
So now back to question, we have to understand what data is copied when we
write =.
Object a=new Object();// here as we know reference of new object will be stored in refvar a.
Then what in actual is passes through.
If we get what data is passed by =(equal operator). We will able to get the object from memory.
Thanks
How we can we get the object from memory by proving hash code?
You can't without access to the internals of the JVM. Even then you would need to scan every object in memory. You would also have the problem than multiple objects with the same hashCode. BTW: By default objects don't have a hashCode until you ask for one.
I think it is possible. Because when I execute environment one. Again and again i get that JVM return the same hash code.
This only works because you are recreating the exact conditions where the hashCode as generated, the slightest changes and you would get different hashCodes.
Means it first find the object in its cache. If it get the reference, it just return it.
By it you mean a cache you would need to maintain, no such cache exists in the JVM.
So now back to question, we have to understand what data is copied when we write =.
Object a=new Object();// here as we know reference of new object will be stored in refvar a.
Then what in actual is passes through.
The reference is passed, like you said. Nothing else.
I guess it is irrelevant since hash code may or may not be related to memory address
take a look documentation
in general each JVM has its own memory stack so whether you can access object from other JVM is depending on JVM implementation and I guess it is rarely possible.

C++ member variable semantics

I have a rather simple question with an inkling as to what the answer is.
My generalized question:
What is actually going on when you declare a member variable, be it public or private, and for all permutations of variable types, e.g. static vs const vs regular variables?
class some_class
{
private:
static const std::string str;
public:
...
}
I have kind of realized that in C++ there is no notion of a non-variable, that is, a non-constructed variable as I was kind of taught to believe exists with languages like Java. The same may also be true in Java, however it is not the way I was taught to think of things so I'm trying to come up with the correct way to think of these non-initialized variables.
public class main {
public static void main(String[] args) {
String str; // A kind of non-variable, or non-constructed variable (refers to null).
str = new String(); // Now this variable actually refers to an object rather than null, it is a constructed variable.
}
}
Since C++ allows you to initialize member variables in the constructor through initializer lists, and I have proven to myself via use of a debugger that the variable doesn't exist before it is initialized through the initializer list (either explicitly or by default), what is, then, actually going on behind the scenes when you declare the member variable?
Tricky question -- it's ambiguous depending on perspective.
From a pseudo-machine perspective, normally adding a non-static plain old data type to a class makes that class type bigger. The compiler also figures out how to align it and relative memory offsets to address it relative to the object in the resulting machine code.
This is pseudo-machine level because at the machine level, data types don't actually exist: just raw bits and bytes, registers, instructions, things like that.
When you add a non-primitive user-defined type, this recurses and the compiler generates the instructions to access the members of the member and so on.
From a higher level, adding members to a class makes the member accessible from instances (objects) of the class. The constructor initializes those members, and the destructor destroys them (recursively triggering destructors of members that have non-trivial destructors, and likewise for constructors in the construction phase).
Yet your example is a static member. For static members, they get stored in a data segment at the machine level and the compiler generates the code to access those static members from the data segment.
Some of this might be a bit confusing. C++ shares its legacy with C which is a hardware-level language, and its static compilation and linking affects its design. So while it can go pretty high-level, a lot of its constructs are still tied to how the hardware, compiler, and linker does things, whereas in Java, the language can make some more sensible choices in favor of programmer convenience without a language design that somewhat reflects all of these things.
Yes and no.
A variable of class type in Java is really a pointer. Unlike C and C++ pointers, it doesn't support pointer arithmetic (but that's not essential to being a pointer--for example, pointers in Pascal didn't support arithmetic either).
So, when you define a variable of class type in Java: String str;, it's pretty much equivalent to defining a pointer in C++: String *str;. You can then assign a new (or existing) String object to that, as you've shown.
Now, it's certainly possible to achieve roughly the same effect in C++ by explicitly using a pointer (or reference). There are differences though. If you use a pointer, you have to explicitly dereference that pointer to get the object to which it refers. If you use a reference, you must initialize the reference--and once you do so, that reference can never refer to any object other than the one with which it was initialized.
There are also some special rules for const variables in C++. In many cases, where you're just defining a symbolic name for a value:
static const int size = 1234;
...and you never use that variable in a way that requires it to have an address (e.g., taking its address), it usually won't be assigned an address at all. In other words, the compiler will know the value you've associated with that name, but when compilation is finished, the compiler will have substituted the value anywhere you've used that name, so the variable (as such) basically disappears (though if you have the compiler generate debugging information, it'll usually retain enough to know and display its name/type correctly).
C++ does have one other case where a variable is a little like a Java "zombie" object that's been declared but not initialized. If you move from an object: object x = std::move(y);, after the move is complete the source of the move (y in this case) can be in a rather strange state where it exists, but about all you can really do with it is assign a new value to it. Just for example, in the case of a string, it might be an empty string--but it also could retain exactly the value it had before the move, or it could contain some other value (e.g., the value that the destination string held before the move).
Even that, however, is a little bit different--even though you don't know its state, it's still an object that should maintain the invariants of its class--for example, if you move from a string, and then ask for the string's length, that length should match up with what the string actually contains--if (for example) you print it out, you don't know what string will print out, but you should not get an equivalent of a NullPointerException--if it's an empty string, it just won't print anything out. If it's a non-empty string, the length of the data that's printed out should match up with what its .size() indicates, and so on.
The other obviously similar C++ type would be a pointer. An uninitialized pointer does not point to an object. The pointer itself exists though--it just doesn't refer to anything. Attempting to dereference it could give some sort of error message telling you that you've attempted to use a null pointer--but unless it has static storage duration, or you've explicitly initialized it, there's no guarantee that it'll be a null pointer either--attempting to dereference it could give a garbage value, throw an exception, or almost anything else (i.e., it's undefined behavior).

Terminology: How to speak about pointers and references in Java

I come from C/C++.
When can I speak about pointers in Java? When about references? Can I say that a variable of type Object holds a reference to some data, ie. to an instance of a class? That this variable points to a class' instance?
If Java is always copy by value, then if I pass that beforementioned variable to a function as a parameter, while the variable itself is getting copied, the content of it is still a reference to the class' instance, so that by any practical means it wasn't really a copy by value, as the instance of the class has not been copied, but the reference was, right?
What do Java developers get annoyed to listen to when speaking with C/C++ developers in this context?
It's somehow a hard to formulate question, I hope I managed to get the point across.
Update To reformulate: Can I speak feely about references and pointers using the meaning I learned while learning C/C++ and rest assured that Java developers are picking up the same meaning I'm putting into it?
Update 2 So would it be correct to asume that the word "pointer" is meaningless / should not be used in Java?
It wil be easier to grasp, if you first understand what is kept where in memory (Stack vs Heap), as you have minimal control over memory management compared to C++. Once that's out of the way, it will be easier to understand what's value and what's reference type and how pass by value and pass by reference works. Java is strictly pass by value, but not every data type is a value type. I hope that helps.
This is a good start:
http://www.journaldev.com/4098/java-heap-memory-vs-stack-memory-difference

Why is assignment to 'this' not allowed in java?

The error I get from the compiler is "The left hand side of an assignment must be a variable". My use case is deep copying, but is not really relevant.
In C++, one can assign to *this.
The question is not how to circumvent assignment to this. It's very simple, but rather what rationale is there behind the decision not to make this a variable.
Are the reasons technical or conceptual?
My guess so far - the possibility of rebuilding an Object in a random method is error-prone (conceptual), but technically possible.
Please restrain from variations of "because java specs say so". I would like to know the reason for the decision.
In C++, one can assign to *this
Yes, but you can't do this = something in C++, which I actually believe is a closer match for what you're asking about on the Java side here.
[...] what rationale is there behind the decision not to make this a variable.
I would say clarity / readability.
this was chosen to be a reserved word, probably since it's not passed as an explicit argument to a method. Using it as an ordinary parameter and being able to reassign a new value to it, would mess up readability severely.
In fact, many people argue that you shouldn't change argument-variables at all, for this very reason.
Are the reasons technical or conceptual?
Mostly conceptual I would presume. A few technical quirks would arise though. If you could reassign a value to this, you could completely hide instance variables behind local variables for example.
My guess so far - the possibility of rebuilding an Object in a random method is error-prone (conceptual), but technically possible.
I'm not sure I understand this statement fully, but yes, error prone is probably the primary reason behind the decision to make it a keyword and not a variable.
because this is final,
this is keyword, not a variable. and you can't assign something to keyword. now for a min consider if it were a reference variable in design spec..and see the example below
and it holds implicit reference to the object calling method. and it is used for reference purpose only, now consider you assign something to this so won't it break everything ?
Example
consider the following code from String class (Note: below code contains compilation error it is just to demonstrate OP the situation)
public CharSequence subSequence(int beginIndex, int endIndex) {
//if you assign something here
this = "XYZ" ;
// you can imagine the zoombie situation here
return this.substring(beginIndex, endIndex);
}
Are the reasons technical or conceptual?
IMO, conceptual.
The this keyword is a short hand for "the reference to the object whose method you are currently executing". You can't change what that object is. It simply makes no sense in the Java execution model.
Since it makes no sense for this to change, there is no sense in making it a variable.
(Note that in C++ you are assigning to *this, not this. And in Java there is no * operator and no real equivalent to it.)
If you take the view that you could change the target object for a method in mid flight, then here are some counter questions.
What is the use of doing this? What problems would this (hypothetical) linguistic feature help you solve ... that can't be solved in a more easy-to-understand way?
How would you deal with mutexes? For instance, what would happen if you assign to this in the middle of a synchronized method ... and does the proposed semantic make sense? (The problem is that you either end up executing in synchronized method on an object that you don't have a lock on ... or you have to unlock the old this and lock the new this with the complications that that entails. And besides, how does this make sense in terms of what mutexes are designed to achieve?)
How would you make sense of something like this:
class Animal {
foo(Animal other) {
this = other;
// At this point we could be executing the overridden
// Animal version of the foo method ... on a Llama.
}
}
class Llama {
foo(Animal other) {
}
}
Sure you can ascribe a semantic to this but:
you've broken encapsulation of the subclass in a way that is hard to understand, and
you've not actually achieved anything particularly useful.
If you try seriously to answer these questions, I expect you'll come to the conclusion that it would have been a bad idea to implement this. (But if you do have satisfactory answers, I'd encourage you to write them up and post them as your own Answer to your Question!)
But in reality, I doubt that the Java designers even gave this idea more than a moment's consideration. (And rightly so, IMO)
The *this = ... form of C++ is really just a shorthand for a sequence of assignments of the the attributes of the current object. We can already do that in Java ... with a sequence of normal assignments. There is certainly no need for new syntax to support this. (How often does a class reinitialize itself from the state of another class?)
I note that you commented thus:
I wonder what the semantics of this = xy; should be. What do you think it should do? – JimmyB Nov 2 '11 at 12:18
Provided xy is of the right type, the reference of this would be set to xy, making the "original" object gc-eligible - kostja Nov 2 '11 at 12:24
That won't work.
The value of this is (effectively) passed by value to the method when the method is invoked. The callee doesn't know where the this reference came from.
Even if it did, that's only one place where the reference is held. Unless null is assigned in all places, the object cannot be eligible of garbage collection.
Ignoring the fact that this is technically impossible, I do not think that your idea would be useful OR conducive to writing readable / maintainable code. Consider this:
public class MyClass {
public void kill(MyClass other) {
this = other;
}
}
MyClass mine = new MyClass();
....
mine.kill(new MyClass());
// 'mine' is now null!
Why would you want to do that? Supposing that the method name was something innocuous rather than kill, would you expect the method to be able to zap the value of mine?
I don't. In fact, I think that this would be a misfeature: useless and dangerous.
Even without these nasty "make it unreachable" semantics, I don't actually see any good use-cases for modifying this.
this isn't even a variable. It's a keyword, as defined in the Java Language Specification:
When used as a primary expression, the keyword this denotes a value that is a reference to the object for which the instance method was invoked (§15.12), or to the object being constructed
So, it's not possible as it's not possible to assign a value to while.
The this in Java is a part of the language, a key word, not a simple variable. It was made for accessing an object from one of its methods, not another object. Assigning another object to it would cause a mess. If you want to save another objects reference in your object, just create a new variable.
The reason is just conceptual. this was made for accessing an Object itself, for example to return it in a method. Like I said, it would cause a mess if you would assign another reference to it. Tell me a reason why altering this would make sense.
Assigning to (*this) in C++ performs a copy operation -- treating the object as a value-type.
Java does not use the concept of a value-type for classes. Object assignment is always by-reference.
To copy an object as if it were a value-type: How do I copy an object in Java?
The terminology used for Java is confusing though: Is Java “pass-by-reference” or “pass-by-value”
Answer: Java passes references by value. (from here)
In other words, because Java never treats non-primitives as value-types, every class-type variable is a reference (effectively a pointer).
So when I say, "object assignment is always by-reference", it might be more technically accurate to phrase that as "object assignment is always by the value of the reference".
The practical implication of the distinction drawn by Java always being pass-by-value is embodied in the question "How do I make my swap function in java?", and its answer: You can't. Languages such as C and C++ are able to provide swap functions because they, unlike Java, allow you to assign from any variable by using a reference to that variable -- thus allowing you to change its value (if non-const) without changing the contents of the object that it previously referenced.
It could make your head spin to try to think this all the way through, but here goes nothing...
Java class-type variables are always "references" which are effectively pointers.
Java pointers are primitive types.
Java assignment is always by the value of the underlying primitive (the pointer in this case).
Java simply has no mechanism equivalent to C/C++ pass-by-reference that would allow you to indirectly modify a free-standing primitive type, which may be a "pointer" such as this.
Additionally, it is interesting to note that C++ actually has two different syntaxes for pass-by-reference. One is based on explicit pointers, and was inherited from the C language. The other is based on the C++ reference-type operator &. [There is also the C++ smart pointer form of reference management, but that is more akin to Java-like semantics -- where the references themselves are passed by value.]
Note: In the above discussion assign-by and pass-by are generally interchangeable terminology. Underlying any assignment, is a conceptual operator function that performs the assignment based on the right-hand-side object being passed in.
So coming back to the original question: If you could assign to this in Java, that would imply changing the value of the reference held by this. That is actually equivalent to assigning directly to this in C++, which is not legal in that language either.
In both Java and C++, this is effectively a pointer that cannot be modified. Java seems different because it uses the . operator to dereference the pointer -- which, if you're used to C++ syntax, gives you the impression that it isn't one.
You can, of course, write something in Java that is similar to a C++ copy constructor, but unlike with C++, there is no way of getting around the fact that the implementation will need to be supplied in terms of an explicit member-wise initialization. [In C++ you can avoid this, ultimately, only because the compiler will provide a member-wise implementation of the assignment operator for you.]
The Java limitation that you can't copy to this as a whole is sort-of artificial though. You can achieve exactly the same result by writing it out member-wise, but the language just doesn't have a natural way of specifying such an operation to be performed on a this -- the C++ syntax, (*this) doesn't have an analogue in Java.
And, in fact, there is no built-in operation in Java that reassigns the contents of any existing object -- even if it's not referred to as this. [Such an operation is probably more important for stack-based objects such as are common in C++.]
Regarding the use-case of performing a deep copy: It's complicated in Java.
For C++, a value-type-oriented language. The semantic intention of assignment is generally obvious. If I say a=b, I typically want a to become and independent clone of b, containing an equal value. C++ does this automatically for assignment, and there are plans to automate the process, also, for the comparison.
For Java, and other reference-oriented languages, copying an object, in a generic sense, has ambiguous meaning. Primitives aside, Java doesn't differentiate between value-types and reference-types, so copying an object has to consider every nested class-type member (including those of the parent) and decide, on a case-by-case basis, if that member object should be copied or just referenced. If left to default implementations, there is a very good chance that result would not be what you want.
Comparing objects for equality in Java suffers from the same ambiguities.
Based on all of this, the answer to the underlying question: why can't I copy an object by some simple, automatically generated, operation on this, is that fundamentally, Java doesn't have a clear notion of what it means to copy an object.
One last point, to answer the literal question:
What rationale is there behind the decision not to make this a variable?
It would simply be pointless to do so. The value of this is just a pointer that has been passed to a function, and if you were able to change the value of this, it could not directly affect whatever object, or reference, was used to invoke that method. After all, Java is pass-by-value.
Assigning to *this in C++ isn't equivalent to assigning this in Java. Assigning this is, and it isn't legal in either language.

Help me understand this pointer vs. value issue

I know this is a dumb question, but its really bugging me.
Take the following:
public <TParseable> LinkedList<TParseable> readAllParseable(
Parseable<TParseable> parseable, boolean close) throws IOException
{
LinkedList<TParseable> list = new LinkedList<TParseable>();
byte[] delim = parseable.getDelimiterValue();
boolean skipNL = parseable.skipNewLines();
while(ready())
{
byte[] data = readTo(delim);
parseable.parse(data);
System.out.println(parseable);
list.add((TParseable)parseable);
}
return list;
}
The println statement outputs the expected toString() value of parseable each time after the call to parseable.parse(data). However, the returned list has the correct number of elements, but they are all equal to the last value of parseable before the loop completed.
Is this because the list.add(xxx) parameter is passed by pointer rather than value?
You only ever have a single instance of parseable in the code you posted. When you call add(parseable) you are adding a reference ("pointer" isn't really correct in Java) to parseable in your list.
By calling it repeatedly, without changing what object parseable refers to, you are simply adding more references to the same object to your list.
New objects are only ever created by the new keyword.
You're putting in the same parseable object into the list each time. Each time parseable parses some data, it is being processed using the same parseable object.
the object parseable is the same through the entire method. I assume that when you call parseable.parse(data) it changes the internal data in parseable. Since you keep putting the same object in the list, you are just operating on the same object every iteration.
I think you conceptual problem is one of terminology. If I change "value" to "state", perhaps it will help clarify things ...
The println statement outputs the
expected toString() state of parseable
each time after the call to
parseable.parse(data).
However, the returned list has the
correct number of elements, but they
are all equal to the last state of
parseable before the loop completed.
In reality, your program is using only one Parseable instance, and the method calls on that instance are changing its state.
Is this because the list.add(xxx)
parameter is passed by pointer rather
than value?
No. It is because the instance's state (as shown by toString()) is changing.
In fact, Java uses pass-by-value semantic for all parameters in method and constructor calls, irrespective of the type. The slightly confusing thing is that the "value" that is passed when you pass an Object / array in Java is a reference.
The three basic parameter passing mechanisms supported by programming languages are:
pass-by-value where you copy the value which might be a primitive value, a pointer / reference value, or (in some languages) a structured value. (In some languages, a value can be copied back on return, but that's just a logical extension of pass-by-value.)
pass-by-reference where you pass the address of a variable in the caller, allowing the callee to change that variable, and/or see the results of something else changing the variable.
pass-by-name which was a "clever" mechanism used in Algol-60 that turned out to be expensive to implement and too difficult for most programmers to use effectively.
I would stay away from using the terminology "pass by pointer". It is really just another way of saying "pass-by-value of a pointer" ... and if you try to think of it as something different, you only end up confused.

Categories

Resources