I am trying to understand the following code snippet. I understand that AutoClosable interface defines a close() method.
protected AutoCloseable fooAction() {
enableFooResources();
return () -> {
disableFooResources()
};
}
What does the construct of return () -> {} mean? How does it return an AutoClosable object.
Appreciate if someone could point to the name of the language construct so that I can look this up.
The () -> ... syntax is called a lambda expression. They are basically an alternative to anonymous classes that has only one method (though they are not compiled into anonymous classes).
Your code is similar to:
protected AutoCloseable fooAction() {
enableFooResources();
return new AutoCloseable() {
#Override
public void close() throws Exception {
SurroundingClass.this.disableResources();
}
}
}
The intention is likely to provide a way for the caller to close whatever resource fooAction is going to do.
Learn more about lambdas here.
Related
Sorry for the somewhat unclear title but hopefully you'll see soon that it wasn't so easy to come up with a better one :)
So I have this interface that extends the Java Supplier #FunctionalInterface by defining one new method and also a default implementation of the Supplier.get() method. My default impl of .get() only wraps a call to the other method in some exception handling.
Then in my code I have different "versions" of this Supplier initialized using lambda notation.
Ex: SomeSupplier s = () -> doSomething();
Not sure why I even tried this because logically I don't understand how this even works, which it does. In my mind when I define my supplier using lambda like this I'm essentially overriding the Supplier.get() method. So how is it that in practice it seems to override my SomeSupplier.getSome() method? And leave the default impl of the .get() method intact?
What am I missing here?
Working example code:
public static void main(String[] args) throws InterruptedException {
SomeSupplier s = () -> getSomeOrException(); // "implements" the Supplier.get(), right?
for (int i = 0; i < 100; i++) {
System.out.println(s.get()); // => "Some!" or "null"
Thread.sleep(2);
}
}
private static String getSomeOrException() throws SomeCheckedException {
if (System.currentTimeMillis() % 10 == 0) {
throw new SomeCheckedException("10 %!");
}
return "Some!";
}
private interface SomeSupplier extends Supplier<String> {
#Override
default String get() {
try {
return getSome();
}
catch (SomeCheckedException e) {
return e.getMessage();
}
}
String getSome() throws SomeCheckedException; // How is this overridden/implemented?
}
private static class SomeCheckedException extends Exception {
public SomeCheckedException(String message) {
super(message);
}
}
}```
Your mistake is that assuming that if a Lambda of a Supplier implements get then a lambda of a SomeSupplier must also implement get.
But instead a Lambda will always implement the single abstract method of an interface* it's about to implement. In Supplier that's get. Your SomeSupplier however has implemented get (with a default method). Therefore getSome() becomes the single abstract method of the functional interface SomeSupplier. So this line:
SomeSupplier s = () -> getSomeOrException();
is roughly analogous to this:
SomeSupplier s = new SomeSupplier() {
String getSome() throws SomeCheckedException() {
return getSomeOrException();
}
};
Note that this implements getSome and not the underlying get method.
*: This is also why functional interfaces can only ever have one abstract method: there's no fallback logic to pick one option if more than one such method exists for a given target type.
I have this construction:
if (Objects.isNull(user.getMartialStatus())) {
user.setMartialStatus(MartialStatus.MARRIED);
}
I have many of them, & I want to optimize code using functional interface.
Okay. I write something like this:
public static <T> void processIfNull(T o, Supplier<Void> s) {
if (Objects.isNull(o)) {
s.get();
}
}
Then, I wait that this code shall work:
processIfNull(user.getMartialStatus(), () -> user.setMartialStatus(MartialStatus.MARRIED));
But IDEA write:
void is not compatible with Void
Please, tell me, what to do.
As the error explains Void is a class which is not equivalent to void. Supplier<Void> expects to return Void like Supplier<String> will expect String object to return.
So your functional interface should be like below.
It has a void apply() which matches the signature of () -> ...
#FunctionalInterface
public interface ActionIfNotNull {
void apply();
}
However when you search for an inbuild functional interface, you can come up with Runnable as Jon Skeet suggested.
Solution
public static <T> void processIfNull(T o, Runnable s) { // instead of you Runnable can use your own functional interface like ActionIfNotNull
if (Objects.isNull(o)) {
s.run();
}
}
As of Java 9 Optional has the ifPresentOrElse method, which could be used for this.
Optional
.ofNullable(user.getMartialStatus())
.ifPresentOrElse(o -> {}, () -> user.setMartialStatus(MartialStatus.MARRIED););
You could also replace the o -> {} by some NOOP Consumer if you like, like this:
private static final Consumer<Object> NOOP = o -> {};
...
Optional
.ofNullable(user.getMartialStatus())
.ifPresentOrElse(NOOP, () -> user.setMartialStatus(MartialStatus.MARRIED););
Anyway, I think the solution Trine came up with, is preferable, because it makes it much clearer, what's going on.
In Kotlin there's an extension method observeOnce (https://code.luasoftware.com/tutorials/android/android-livedata-observe-once-only-kotlin/) which is the behaviour I'm looking to replicate in Java. It's to my understanding from googling that you can't use Kotlin extension methods in java (may be wrong), so I've got two options of using SingleEventLiveData which I've implemented and am not keen on, and removing my observer once used;
final LiveData<List<String>> stringsLiveData = mViewModel.getStrings();
stringsliveData.observe(getViewLifecycleOwner(), strings -> {
// Do stuff with data here
stringsLiveData.removeObservers(getViewLifecycleOwner());
});
Is there an equivilant method that can be used as the link above so;
mViewModel.getStrings().observeOnce(getViewLifecycleOwner(), strings -> {
//Do stuff here
});
Edit: As per the accepted answer below (modified to compile) I've got;
class LiveDataUtils {
public static <T> void observeOnce(LiveData<T> liveData, Observer<T> observer) {
liveData.observeForever(o -> {
liveData.removeObserver(observer);
observer.onChanged(o);
});
}
}
and a simple usage of this;
LiveDataUtils.observeOnce(
mViewModel.getStrings(),
strings -> {
// Do some work here
}
);
Every Kotlin extension function is resolved statically, which means that you can do the same in Java by using static functions. It is not as readable or as intuitive as the extension functions, but it does the same job.
Create a util class with a static method:
public class LiveDataUtils {
public static <T> void observeOnce(LiveData<T> liveData, Observer<T> observer) {
liveData.observeForever(new Observer<T>() {
#Override
public void onChanged(T t) {
liveData.removeObserver(this);
observer.onChanged(t);
}
});
}
}
I haven't tested the code, so it might have some errors. The point was to show you how you can replace extension functions in Java.
EDIT: Updated according to follow up by #Marek Potkan, since this is the accepted answer. As I mentioned, I haven't tested the code and I provided a wrong reference by mistake.
#deluxe1 answer wouldn't work. It is removing observer called observer, but that's not the one which is used in the observeForever method. Expanded version should be used instead of the lambda function here:
public static <T> void observeOnce(LiveData<T> liveData, Observer<T> observer) {
liveData.observeForever(new Observer<T>() {
#Override
public void onChanged(T t) {
liveData.removeObserver(this);
observer.onChanged(t);
}
});
}
I have tested both approaches.
What is the real reason that in Java, and similar languages, must be explicitly said that a class implements an interface?
Imagine implicit implementation:
interface Flyer { void fly(); }
public class Duck { public void fly() {...} }
public class Plane { public void fly() {...} }
public class Hoe { void hangAround() {...} }
void startFlying(Flyer flyer) {...}
void race() {
...
startFlying(duck); // OK
startFlying(plane); // OK
startFlying(hoe); // Compilation error.
}
Compiler knows method's signatures, return type (and modifier, of course). At this point it seems clear that there is no need to explicitly specify that Duck and Plane implements Flyer.
I would said that "implements XYZ" may be removed from Java without worries.
No difference, check at compilation time so it's OK.
In the other hand:
#JBNizet mentioned different meaning of methods with the same signature and return type.
I will use his example:
interface Runner { void run(); }
public class Guy { public void run(); }
public class Gal { public void run(); }
void startRunning(Runner r) {...}
void race() {
startRunning(guy); // OK
startRunning(gal); // OK
startRunning(runnableThread); // OK
}
OK for compiler, OK for startRunning() (OK for me). It's up to your philosophy if this is OK for you or not.
Explicit:
public class Guy **implements Runner **{ public void run(); }
public class Gal **implements Runner **{ public void run(); }
In bold (or text between ** and **) is the price which you must pay for
void race() {
startRunning(guy); // OK
startRunning(gal); // OK
startRunning(runnableThread); // Compilation error!
}
Note compilation error so you can see the issue before testing.
If it's intended to use runnableThread in startRunning() as well you must do it even more explicitly (enough time to realize what you are doing).
"I wondered how much of time is wasted by resolving issues related to typing "implements XYZ" compared to time wasted by resolving issues with implicitly implemented interfaces. If it's way more better for implicitly implemented interface then I hate Java designers for their decision and that they force us to belive it's better :-)"
Ladybug and airbus (and duck)
I think the issue with implicitly implemented interface is only theoretical and rare in real.
public class Airbus {
void takeOff() {...}
void land() {...}
Passenger[] getPassengers() {...}
}
public class Ladybug {
void takeOff() {...}
void land() {...}
}
public class Duck {
void takeOff() {...}
void land() {...}
Passenger[] getPassengers() {...}
}
public interface Aircraft {
void takeOff();
void land();
Passenger[] getPassengers();
}
public void fly(Aircraft aircraft) {
aircraft.takeOff();
for (Passenger p : aircraft.getPassengers()) {...}
aircraft.land();
}
public void airport() {
fly(airbus_a380); // OK
fly(ladybug); // Compilation error, does not match Aircraft requirements.
fly(duck); // OK
}
public interface Lander {
void land();
}
public void landAtMeadow(Lander lander) {...}
public void meadow() {
landAtMeadow(airbus_a380); // OK
landAtMeadow(duck); // OK
landAtMeadow(ladybug); // OK
}
All of them are matching requirements of landAtMeadow so they can be used in that context. Even it may not be possible to land at meadow for airbus_a380 (In other word testing is required) you need to land there in emergency.
Do not forget that landAtMeadow() may have more specific requirements like
public interface Lander { void landAtLimitedArea(int size); }
to say that the space is limited, so if airbus_a380 does not support this method then you have compilation error here.
Java is a strong typed language, so the assignation of an instance to an interface typed variable must be validated at compile time. This can only be done by explicitly declared interface implementations.
As others have said, this is a basic characteristic of the Java language. It's there for good reasons, folks who are doing serious largescale programming like it, and there's absolutely no reason to change it.
If it bothers you, I strongly recommend that you find another language that is more weakly typed and use that instead. There are a fair number of languages these days which can be compiled into Java bytecodes and used in a Java environment, so you might not even have to give up the flexibility of being able to run in a JVM.
My friend In a strongly typed languages, for ex: in C or Java, when a variable or reference is declared, it must be informed to the compiler what data type the variable or reference is of
When a class is declared to implement an interface X then any other method working with interface X is sure that all the necessary methods are implemented in the class (and therefore they do not need to check every time if needed method is implemented). If there was no such declaration, then any method using classes which implement X would need to:
ensure that the class of object whith which the method is working implements all methods necessary (so go through all the methods of the class searching the ones you want every time you expect to work with interface X - instead of doing this once, at compilation).
have many error handling lines of code implemented (what to do, if I expect method A to do something, but method A it is not there at all?)
Static typing adds much to code's safety in general, as many errors are possible to detect at compilation. Why try to change Java from staticaly to dynamicaly typed? There are many dynamicaly typed languages out there, with their pluses and minuses, ready to use (Python, for example).
If I have the method public void send() { /* some code */ } in a class and have a child of this class also have a method public void send() { /* some code*/ }, how do I ensure that the child must call super.send() somewhere in the send() method that it's trying to override?
I was wondering about this because I've written in APIs where if you don't call the super of that method when overriding it, it'll throw an exception telling me that I haven't called the super method. Is this hard coded or can this be done with some keywords in Java?
You can't really, but you can...
class MySuperClass {
public final void send() {
preSend();
// do the work...
postSend();
}
protected void preSend() {
// to be overridden in by sub classes
}
protected void postSend() {
// to be overridden in by sub classes
}
}
You can do this by adding an abstract method (don't see another way) :
abstract class MyClass
{
public final void send() // forbid changing this.
{
// do something
doSend():
}
protected abstract doSend(); // no external calls
}
http://en.wikipedia.org/wiki/Call_super
What you're trying to do is an anti-pattern; you can do it (many Java core classes do), but you shouldn't - unless you have a really good reason for it.
Except for this bit, all answers provided here are correct.
Conceptually, this is like 'delegating to a child'. To achieve this, the parent class should implement final method which invoke an abstract method, which the child is supposed to implement.
abstract class Parent {
public final void invoke() {
// pre invoke code
doInvoke():
// post invoke code
}
protected abstract doInvoke(); // child should implement this
}
You can't really force a subclass to call the base one. One thing you can do is to change your send method into a base (final) "send" and a "sendcore" (virtual) which would be overriden by the subclasses. The base "send" would set some flag stating that "sendcore" hasn't been called, and then call "sendcore". When it returns it can check whether the child "sendcore" has called the base class.
There is no keyword that enforces this. In my opinion, you either
Provide the subclass with all the information (via protected methods or what not) it needs to completely override and change the send call itself, or...
Document the API so that it is known that they must eventually call send themselves via super. I would imagine most people who are overriding a superclass method would do this if enough of the class is abstracted anyway.
There's nothing built into Java to enforce calling a superclass method. One approach to this is to use private flags in the superclass together with a delegation method. Something like this:
public class Super {
private boolean inSend;
private boolean superCalled;
public final void send() {
inSend = true;
superCalled = false;
doSend();
inSend = false;
if (!superCalled) {
throw new IllegalStateException("Failed to call super.doSend()");
}
}
protected void doSend() {
if (!inSend) {
throw new IllegalStateException("Cannot call doSend() directly");
}
superCalled = true;
// base class functionality
}
}