How come two method references are compiled into two different addresses? - java

I reference the same method twice but the references are different. See this example:
import java.util.function.Consumer;
public class MethodRefTest {
public static void main(String[] args) {
new MethodRefTest();
}
public MethodRefTest() {
Consumer<Integer> a = this::method;
System.out.println(a);
Consumer<Integer> b = this::method;
System.out.println(b);
}
public void method(Integer value) {
}
}
The output is:
MethodRefTest$$Lambda$1/250421012#4c873330
MethodRefTest$$Lambda$2/295530567#776ec8df
Are method references nothing more than syntactic sugar for anonymous classes? If not, what do I have to do to always get the same method reference? (Aside from storing a reference once in a field to work with.)
(Application: I thought of method references as a prettier way of observer implementation. But with different references each time it's impossible to remove an observer from an observable once it's added.)

Are method references nothing more than syntactic sugar for anonymous classes?
Correct. They aren't necessarily always implemented as heavyweight as that, but conceptually it's all they are.
If not, what do I have to do to always get the same method reference? (Aside from storing a reference once in a field to work with.)
Store the reference in a field. That's the answer. (Sorry.)

You ask,
Are method references nothing more than syntactic sugar for anonymous classes?
The JLS says that
Evaluation of a method reference expression produces an instance of a functional interface type
(JLS 8, section 15.13)
That doesn't explicitly require an anonymous class, but it does require some class, and it does not provide a mechanism for naming that class. I can imagine alternatives, but using the existing anonymous class mechanism seems pretty natural.
It is plausible that an implementation could recognize multiple references to the same method and use the same anonymous class for them, but such behavior is by no means required, and you have demonstrated that your implementation does not do it. Even if an implementation did do that, however, the JLS is at minimum suggestive that each evaluation of a method reference expression produces a new object.
You go on,
If not, what do I have to do to always get the same method reference? (Aside from storing a reference once in a field to work with.)
Your only guaranteed mechanism is to evaluate the method reference just once, and to then hold on to a reference to the resulting object as long as you have need of it. Storing the reference in a field, as #JohnKugelman describes, is one variation on that, but depending on the scope in which you need to refer to the same method reference object, it might suffice to store it in a local variable or to pass it around via method arguments.

Generally speaking the easiest and efficient way is storing the reference either in a field or a (local) variable.

First of all, the toString() output of the object generated for a method reference is entirely unspecified, hence, you cannot draw any conclusions about the object’s identity from there. Also, the hexadecimal number is an implementation dependent hashcode that is rarely an address. The only reliable way to check the identity of the object is to do a==b.
Still, these objects are indeed different, but that’s an implementation detail. As explained in Does a lambda expression create an object on the heap every time it's executed?, the JVM has a lot of freedom regarding object reuse, but the current HotSpot/OpenJDK implementation will reuse objects only for non-capturing expressions and this::method is capturing the this reference. Also, as shown by the code of your question, each occurrence of this::method in your code will even get its own generated class.
This is explained in Is method reference caching a good idea in Java 8?, which also concludes that you shouldn’t keep these instances for performance reasons. But in your case, when you want to deregister a listener reliably, keeping the reference in a variable is the only way to do it. As even for a single occurrence of a non-capturing expression, for which the current implementation will provide the same object, there is no guaranty that this will work, as this reuse still is an implemen­tation dependent behavior.

Related

Can Java lambda expressions be guaranteed not to hold a reference to `this`?

If a lambda expression does not refer to any methods or fields of the surrounding instance, does the language guarantee that it doesn't hold a reference to this?
In particular, I want to use lambda expressions to implement java.lang.ref.Cleaner actions. For example:
import static some.Global.cleaner;
public class HoldsSomeResource {
private final Resource res;
private final Cleanable cleanup;
public HoldsSomeResource(Resource res) {
this.res = res;
cleanup = cleaner.register(this, () -> res.discard());
}
public void discard() {
cleanup.clean();
}
}
Clearly, it would be bad if the lambda expression implementing the cleanup action were to hold a reference to this, since it would then never become unreachable. It seems to work when I test it right now, but I can't find the obvious reference in the JLS that it is guaranteed to be safe, so I'm slightly worried that I might run into problems in alternative and/or future Java implementations.
The specification does indeed not mention this behavior, but there is a statement in this document from Brian Goetz:
References to this — including implicit references through unqualified field references or method invocations — are, essentially, references to a final local variable. Lambda bodies that contain such references capture the appropriate instance of this. In other cases, no reference to this is retained by the object.
While this isn’t the official specification, Brian Goetz is the most authoritative person we can have to make such a statement.
This behavior of lambda expressions is as intentional as it can be. The cited text continues with
This has a beneficial implication for memory management: while inner class instances always hold a strong reference to their enclosing instance, lambdas that do not capture members from the enclosing instance do not hold a reference to it. This characteristic of inner class instances can often be a source of memory leaks.
Note that this other behavior, inner class instances always holding an implicit reference to the outer this instance, also does not appear anywhere in the specification. So when even this behavior, causing more harm than good if ever being intentional, is taken for granted despite not appearing in the specification, we can be sure that the intentionally implemented behavior to overcome this issue will never be changed.
But if you’re still not convinced, you may follow the pattern shown in this answer or that answer of delegating to a static method to perform the Cleaner registration. This has the benefit of also preventing accidental use of members while still being simpler than the documentation’s suggested use of a nested static class.
I think you're safe. It's not an aspect of the JIT or a garbage collector implementation (stuff from "java.exe") ; this is done directly by the compiler ("javac.exe"). It's not going to 'backslide' and inject useless and potentially pricey variables. It also means you are not dependent on a JVM's behaviour: you're merely dependent on a compiler's behaviour. For starters, there aren't all that many (ecj and javac that's pretty much it - all others you might be thinking of are forks of those, or are wrappers around those), and I'm pretty sure both ecj and javac don't capture the this now and presumably never will in the future.
A bigger issue is that javac certainly won't complain if you 'accidentally' do happen to capture anything that requires the this ref; that will lead to the this ref getting silently captured and ruining your cleanup library rather thoroughly. It feels like you've designed a library here where it's rather all too easy to shoot yourself in the foot.
I'm not quite sure what you can do to fix this. Possibly you can lean into it and use ASM or bytebuddy or similar to tear the class open1 and doublecheck that the this ref is not seeing capture. It's probably not worth the potentially sizable time it'd take to chase down all the refs to ensure that this isn't captured in a roundabout fashion (where the lambda captures variable y, and y has a field of type Bar pointing at some instance and that instance has a field whose value is a ref back to the original this, thus, preventing collection), but checking for direct capture is potentially interesting. Possibly even only in an assert statement so any testcase that does it will result in an AssertionError thrown, failing the test, letting you know this error was made.
[1] You can get the bytes of any class with String.class.getResourceAsStream("String.class") - you can read that InputStream and feed it into ASM / bytebuddy / etc. The costs of running a class through such a loop are considerable, of course.

How to determine if a Java method modifies an object passed as parameter

I come from a C++ background and I am currently learning Java. One question arose when I have tried using some third party libraries. How do I determine if the call to a method taking an object reference as parameter modifies the object?
In C++ this is clear thanks to the use of the const keyword. If the method signature is:
void foo(Boo& boo);
I know that the referenced object might be modified, while if the method signature is:
void foo(const Boo& boo);
The compiler guarantees that the referenced object is not modified.
I haven't seen something analogous in Java, as only the reference itself can be declared final, not the referenced object, and a final argument doesn't make much sense in the first place since it is passed by value anyway. Therefore, when I see a method such as:
void foo(Boo boo) {...}
How do I determine if the object referenced by boo is modified inside the body of the function (maybe using annotations)? If there is no way to know, is there some widely used convention or some best practices to avoid confusion and bugs?
how do I determine if the object referenced by boo is modified inside the body of the function (maybe using annotations)?
The only way is to read the code unfortunately.
If there is no way to know, is there some widely used convention or some best practices to avoid confusion and bugs?
The common convention is to pass an object which cannot be modified, using a wrapper if needed. This ensure the class cannot modify the object.
List<String> readOnly = Collections.unmodifiableList(list);
If the object is Cloneable, you can also use clone() but another common approach is to use a copy.
List<String> readOnly = new ArrayList<>(list);
If you care about such behaviour, unit tests can show whether a method modifies an object or not. If you have unit tests already, it is usually one or two lines extra to check for this.
There's no such facility built in to the language, unfortunately. A good defensive practice is to define the data objects you pass around as immutable (i.e., without any public method that allows modifying their state). If you are really concerned about this, you could copy/clone an object before passing it to a method you don't trust, but this is usually a redundant precaution.
NOTE: this answer is a more detailed version of
You can also write purity or side-effect annotations in your code — mernst
There exists the Checker Framework among the various things it can check at compile-time via annotations is the IJG Immutablity checker. This checker allows you to annotate object references with #Immutable or #ReadOnly.
The problem is that you often would have to annotate the library yourself. To ease your task the Checker Framework can automatically infer part of the annotations; you will still have to do much yourself.
A side effect analysis is not built into the Java language.
You can perform side effect analysis via manual inspection, but several tools exist to automate the process.
You can use an inference tool (1, 2, 3) to detect whether your code side-effects a parameter.
You can also write purity or side-effect annotations in your code and then use a checking/verification tool (1, 2) to ensure that your code conforms to the annotations you have written.
All of the above-linked tools have limitations, but you might find them useful. If you know of other tools, mention them in comments.
How do I determine if the object referenced by boo is modified inside
the body of the function (maybe using annotations)?
I must agree with other answers that there is no direct way to determine that method will modify your object or not and yes to make sure that method can not modify your Object you all have to do it is from your side.
If there is no way to know, is there some widely used convention or
some best practices to avoid confusion and bugs?
Here the method name comes to the scene. Moving ahead with the naming convention of method we have to take a look at some method declarations which clearly convince you that your Object will not be changed at all.
For example, You know that Arrays.copyOf will not change your actual array, System.out.println(boo) will not change your boo
Method names are real weapons to provide as much information as possible to the method user.(Yes! it's always not possible but quite a good practice to follow.)
Let's consider it in your case that say printBoo will only print, copyBoo will only copy, clearBoo will reset all attributes, checkAndCreateNewBoo will check your boo Object and create new if required.
So, ultimately if we can use them in a proper way caller can be assured with the fact that Object will remain the same after calling the method.
As everyone says, prefer using immutable objects and also avoid void methods
The available purposes of methods like this
void foo(Boo boo) {...}
are to change the state of the object itself or change the object passed as a parameter
void completOrder(Order order) { ... }
//or
void parserTokenEnded(String str) { ... }
There is a way , that the method developer should mark parameter as final , if it is not going to modify the parameter.
public void test(final Object param)
However very few people follow this , so it is difficult to know. However good programmer follow this rule , especially writing the api. If you want to write method and expose it. Make param final to indicate that passed object is not going to be modified.

Is passing 'this' in a method call accepted practice in java

Is it good/bad/acceptable practice to pass the current object in a method call. As in:
public class Bar{
public Bar(){}
public void foo(Baz baz){
// modify some values of baz
}
}
public class Baz{
//constructor omitted
public void method(){
Bar bar = new Bar();
bar.foo(this);
}
}
Specifically, is the line bar.foo(this) acceptable?
There's nothing wrong with that. What is NOT a good practice is to do the same inside constructors, because you would give a reference to a not-yet-completely-initialized object.
There is a sort of similar post here: Java leaking this in constructor
where they give an explanation of why the latter is a bad practice.
There's no reason not to use it, this is the current instance and it's perfectly legitimate to use. In fact there's often no clean way to omit it.
So use it.
As it's hard to convince it's acceptable without example (a negative answer to such a question is always easier to argument), I just opened one of the most common java.lang classes, the String one, and of course I found instances of this use, for example
1084 // Argument is a String
1085 if (cs.equals(this))
1086 return true;
Look for (this in big "accepted" projects, you won't fail to find it.
Yes, but you should be careful about two things
Passing this when the object has not been constructed yet (i.e. in its constructor)
Passing this to a long-living object, that will keep the reference alive and will prevent the this object from being garbage collected.
It's perfectly normal and perfectly acceptable.
this stands for the current object. What you are doing is sytatically correct but i don't see a need of this if you are calling the method in the same class.
It is bad practice to pass the current object in a method call if there less complex alternatives to achieve the same behaviour.
By definition, a bidirectional association is created as soon as this is passed from one object to another.
To quote Refactoring, by Martin Fowler:
Change Bidirectional Association to Unidirectional (200)
Bidirectional associations are useful, but they carry a price. The
price is the added complexity of maintaining the two-way links and
ensuring that objects are properly created and removed. Bidirectional
associations are not natural for many programmers, so they often are a
source of errors
...
You should use bidirectional associations when you need to but not
when you don’t. As soon as you see a bidirectional association is no
longer pulling its weight, drop the unnecessary end.
So, theoretically, we should be hearing alarm bells when we find we need to pass this and try really hard to think of other ways to solve the problem at hand. There are, of course, times when, at last resort, it makes sense to do it.
Also it is often necessary to corrupt your design temporarily, doing 'bad practice things', during a longer term refactoring of your code for an overall improvement. (One step back, two steps forward).
In practice I have found my code has improved massively by avoiding bidirectional links like the plague.
Yes. you can use it.Its just common in programming to pass this.But there are pros and cons about using that.Still it is not hazardous to do so.
Just to add one more example where passing this is correct and follows good design: Visitor pattern. In Visitor design pattern, method accept(Visitor v) is typically implemented in a way it just calls v.visit(this).
Acceptable
Snippet from Oracle JAVA docs:
Within an instance method or a constructor, this is a reference to the
current object — the object whose method or constructor is being
called. You can refer to any member of the current object from within
an instance method or a constructor by using this.
Using this with a Field
The most common reason for using the this keyword is because a field
is shadowed by a method or constructor parameter.
Everything in java is passed by value. But objects are NEVER passed to the method!
When java passes an object to a method, it first makes a copy of a reference to the object, not a copy of the object itself. Hence this is pefectly used method in java. And most commonly followed usage.

In Java, do methods that don't use static or class variables need to be synchronized?

Do methods that only use local variables inside suffer any threading issues ?. Somewhere it was mentioned that the method with local variables are copied to each thread stack frame to work with and do not need to synchronized for multithreaded implementation unless it uses class level or static references/variables ?
If your method only operates on parameters and locally-defined (as opposed to class member) variables then there are zero synchronization problems to worry about.
But...
This means any mutable reference types you use must live and die only within the scope of your method. (Immutable reference types aren't a problem here.) For example this is no problem:
int doSomething(int myParameter)
{
MyObject working_set = new MyObject();
interim = working_set.doSomethingElse(myParameter);
return working_set.doSomethingElseAgain(interim);
}
A MyObject instance is created within your method, does all of its work in your method and is coughing up blood, waiting to be culled by the GC when you exit your method.
This, on the other hand, can be a problem:
int doSomething(int myParameter)
{
MyObject working_set = new MyObject();
interim = working_set.doSomethingElse(myParameter);
another_interim = doSomethingSneaky(working_set);
return working_set.doSomethingElseAgain(another_interim);
}
Unless you know for sure what's going on in doSomethingSneaky(), you may have a need for synchronization somewhere. Specifically you may have to do synchronization on the operations on working_set because doSomethingSneaky() could possibly store the reference to your local working_set object and pass that off to another thread while you're still doing stuff in your method or in the working_set's methods. Here you'll have to be more defensive.
If, of course, you're only working with primitive types, even calling out to other methods, passing those values along, won't be a problem.
Does methods that only use local variables inside, do not suffer any threading issues ?
True in a very simplistic sense, but lets be clear - I think this is only true if:
such a method uses only local variables that are primitives or references to mutable instances that cannot otherwise be accessed outside the method by any other means.
such a method invokes only methods that are thread-safe.
Some ways these rules could be violated:
A local variable could be initialized to point to an object that is also accessible outside the method. For example, a local variable could point to a singleton (Foo bar = Foo.getSingleton()).
A local instance held by a local variable could "leak" if the instance is passed as a argument to an external method that keeps a reference to the instance.
A class with no instance variables and with only a single method with no local variables could still call the static method of another class that is not thread-safe.
The question is very generic, so please do not expect any specificity from my answer.
1_ We need to more careful with static methods than say instance methods.
2_ #Justmycorrectopinion is about right, but some of the terms he described needs to be more elaborated to be perfect. ( Even if the static method, only works on local variable, there is still possibility of race condition.)
3_ For me there are simple rules that have helped me analyze thread safety.
Understand if each components encapsulated within it is shareable or not. So the simplest solution is to reduce the scope of all variable and only increase scope if absolutely necessary and if component perform mutation on a object, its usually not thread safe.
4_ Use tooling support to perform static code analysis on thread safety. (Idea has checkthread plugin).
5_ Never use static method to perform object mutation. If calling static variable causes object mutation, then the developer is just circumventing OOPS.
6_ Always document thread safety. Remember some method may not need to be synchronized when you develop, but can be made not thread safe very easily.
7_ Last but probably my most important point, make sure most of your objects are immutable. In my experience, most of the time, I never had to make many of my objects mutable. (In rare cases when object state needs to be changed, defensive copying / New Object Creation is almost always better. )
You do not need to worry about local variables. Instance variables however are something to care about.

Java: Rationale of the Object class not being declared abstract

Why wasn't the java.lang.Object class declared to be abstract ?
Surely for an Object to be useful it needs added state or behaviour, an Object class is an abstraction, and as such it should have been declared abstract ... why did they choose not to ?
An Object is useful even if it does not have any state or behaviour specific to it.
One example would be its use as a generic guard that's used for synchronization:
public class Example {
private final Object o = new Object();
public void doSomething() {
synchronized (o) {
// do possibly dangerous stuff
}
}
}
While this class is a bit simple in its implementation (it isn't evident here why it's useful to have an explicit object, you could just declare the method synchronized) there are several cases where this is really useful.
Ande, I think you are approaching this -- pun NOT intended -- with an unnecessary degree of abstraction. I think this (IMHO) unnecessary level of abstraction is what is causing the "problem" here. You are perhaps approaching this from a mathematical theoretical approach, where many of us are approaching this from a "programmer trying to solve problems" approach. I believe this difference in approach is causing the disagreements.
When programmers look at practicalities and how to actually implement something, there are a number of times when you need some totally arbitrary Object whose actual instance is totally irrelevant. It just cannot be null. The example I gave in a comment to another post is the implementation of *Set (* == Hash or Concurrent or type of choice), which is commonly done by using a backing *Map and using the Map keys as the Set. You often cannot use null as the Map value, so what is commonly done is to use a static Object instance as the value, which will be ignored and never used. However, some non-null placeholder is needed.
Another common use is with the synchronized keyword where some Object is needed to synchronize on, and you want to ensure that your synchronizing item is totally private to avoid deadlock where different classes are unintentionally synchronizing on the same lock. A very common idiom is to allocate a private final Object to use in a class as the lock. To be fair, as of Java 5 and java.util.concurrent.locks.Lock and related additions, this idiom is measurably less applicable.
Historically, it has been quite useful in Java to have Object be instantiable. You could make a good point that with small changes in design or with small API changes, this would no longer be necessary. You're probably correct in this.
And yes, the API could have provided a Placeholder class that extends Object without adding anything at all, to be used as a placeholder for the purposes described above. But -- if you're extending Object but adding nothing, what is the value in the class other than allowing Object to be abstract? Mathematically, theoretically, perhaps one could find a value, but pragmatically, what value would it add to do this?
There are times in programming where you need an object, some object, any concrete object that is not null, something that you can compare via == and/or .equals(), but you just don't need any other feature to this object. It exists only to serve as a unique identifier and otherwise does absolutely nothing. Object satisfies this role perfectly and (IMHO) very cleanly.
I would guess that this is part of the reason why Object was not declared abstract: It is directly useful for it not to be.
Does Object specify methods that classes extending it must implement in order to be useful? No, and therefor it needn't be abstract.
The concept of a class being abstract has a well defined meaning that does not apply to Object.
You can instantiate Object for synchronization locks:
Object lock = new Object();
void someMethod() {
//safe stuff
synchronized(lock) {
//some code avoiding race condition
}
}
void someOtherMethod() {
//safe code
synchronized(lock) {
//some other stuff avoiding race condition
}
}
I am not sure this is the reason, but it allows (or allowed, as there are now better ways of doing it) for an Object to be used as a lock:
Object lock = new Object();
....
synchronized(lock)
{
}
How is Object any more offensive than null?
It makes a good place marker (as good as null anyway).
Also, I don't think it would be good design to make an object abstract without an abstract method that needs to go on it.
I'm not saying null is the best thing since sliced bread--I read an article the other day by the "Inventor" discussing the cost/value of having the concept of null... (I didn't even think null was inventable! I guess someone somewhere could claim he invented zero..) just that being able to instantiate Object is no worse than being able to pass null.
You never know when you might want to use a simple Object as a placeholder. Think of it as like having a zero in a numerical system (and null doesn't work for this, since null represents the absence of data).
There should be a reason to make a class abstract. One is to prevent clients from instantiating the class and force them into using only subclasses (for whatever reasons). Another is if you wish to use it as an interface by providing abstract methods, which subclasses must implement. Probably, the designers og Java saw no such reasons, so java.lang.Object remains concrete.
As always, Guava comes to help: with http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Optional.html
Stuff here can be used to kill nulls / Object instances for "a not-null placeholder" from the code.
There are entirely seperated questions here:
why did not they make Object abstract?
how much disaster comes after if they decide to make it abstract in a future release?
I'll just throw in another reason that I've found Object to useful to instantiate on its own. I have a pool of objects I've created that has a number of slots. Those slots can contain any of a number of objects, all that inherit from an abstract class. But what do I put in the pool to represent "empty". I could use null, but for my purpose, it made more sense to insure that there was always some object in each slot. I can't instantiate the abstract class to put in there, and I wouldn't have wanted to. So I could have created a concrete subclass of my abstract class to represent "not a useful foo", but that seemed unnecessary when using an instance of Object was just as good..in fact better, as it clearly says that what's in the slot has no functionality. So when I initialize my pool, I do so by creating an Object to assign to each slot as the initial condition of the pool.
I agree that it might have made sense for the original Java crew to have defined a Placeholder object as a concrete subclass of Object, and then made Object abstract, but it doesn't rub me wrong at all that they went the way they did. I would then have used Placeholder in place of Object.

Categories

Resources