Earlier quoted context omitted.
== should never have been used for that method, which is very rarely what you want. The right thing is probably to deprecate == on nonprimitive types, replacing it with a longer name that's clearer about what it means.
Or make == call .equals and add a .referenceEquals method for the case where you actually want to check for reference equality. This is what Scala and C# do.
An Opinionated Guide to Modern Java Development, Part 1
351–360 of 402 posts
Re: An Opinionated Guide to Modern Java Development, Part 1
#352Earlier quoted context omitted.
> Even J2ME is more compatible with its big brother than Android. Are you serious? J2ME is even more crippled than Android's Java (no reflection, no Swing, no AWT and stuck in Java 1.4). J2ME has been dead for more than half a decade and we have Android to thank for that. Good riddance.
I'm not sure where you get your information about this, but J2ME 8 was released alongside Java 8: http://www.oracle.com/technetwork/java/embedded/overview/jav...
Also missing:
Reflection
Serialization
Lambda expressions (JSR 335)
JNI and application native code
User-defined class loaders
Full annotations support (Runtime annotations)
Thread groups and demon threads
Full Math APIs (with BigDecimals)
Concurrency utilities
Full security APIs
Full collection APIs (Sorted collection classes)
Source: http://docs.oracle.com/javame/config/cldc/opt-pkgs/api/cldc/...Re: An Opinionated Guide to Modern Java Development, Part 1
#353Earlier quoted context omitted.
Indeed, Option in Scala has the same problem. I understand null is needed for backwards compatibility, but it makes Option the poor man's Maybe...
> Indeed, Option in Scala has the same problem eh? scala> val safe = Option(null) safe: Option[Null] = None
// The type of 'unsafe' is Option[String]
var unsafe = Option("some string")
unsafe = null
unsafe map println
gives Exception in thread "main" scala.MatchError: null
effectively a NullPointerException. This would be impossible for a true Option (aka Maybe) type. The problem is introduced because Scala, for backwards compatibility reasons, still allows the assignment of null; this lowers the usefulness of pattern matching against Option types.--
edit: you could object to my use of var (and you should). Ok, let's re-write it to be a val:
def unsafeFunction(x: Option[String]): Option[String] = {
x orElse null
}
...
val unsafe = unsafeFunction(None)
unsafe map println
...and I still get the NPE. Note that in this case you can easily see how I introduced the problem, but the point is that the signature for unsafeFunction should guarantee null is not a possible return value.Re: An Opinionated Guide to Modern Java Development, Part 1
#354Earlier quoted context omitted.
That's pretty contrived, when would you _ever_ wrap a thing that could be null in a Some? Even so, to continue with your example: scala> x foreach println null x.get res2: Null = null Hey, what do you know, no NPE. Try harder ;-)
Ok fair point re it being contrived! Although (having just re-read it), the original post's complaint was actually that: > the compiler (afaik) doesn't prevent you from setting an Optional field to null ie scala> val option: Option[Any] = null option: Option[Any] = null
Re: An Opinionated Guide to Modern Java Development, Part 1
#355Earlier quoted context omitted.
Dalvik is being slowly replaced by ART (Android RunTime). Also, you can pretty easily hack Java 7 or even Java 8 into Android to use lambdas. Official, default support is coming soon. http://tools.android.com/tech-docs/new-build-system/user-gui... http://zserge.com/blog/android-lambda.html
>> Official, default support is coming soon. Default support of ART or Java 8? If Java 8, how do you know this? Citation needed ;)
Arguing whether Java 8 will be completely supported or not ignores the nature of the Android API. Android doesn't even support 100% of Java 6 because it is not a desktop JDK and does not intend to replicate everything.
However, the Android team has actively been adding default support of Java 7 features piece by piece in recent months. They intend to handle Java 8 in the same manner. It's not clear which features will be supported in what version of Android, but lambdas are clearly a priority and can already be used today by early adopters using retrolambda.
Re: An Opinionated Guide to Modern Java Development, Part 1
#356Earlier quoted context omitted.
Ok fair point re it being contrived! Although (having just re-read it), the original post's complaint was actually that: > the compiler (afaik) doesn't prevent you from setting an Optional field to null ie scala> val option: Option[Any] = null option: Option[Any] = null
Exactly, that was my complaint. It makes elegant pattern matching against Option types (the whole point of using them, in fact) less than useful. Now, in Scala-land, you have to check that they aren't null, which sucks.
Re: An Opinionated Guide to Modern Java Development, Part 1
#357Earlier quoted context omitted.
He knows what he is talking about & his description matches the explanation by Brian Goetz. So unless I'm missing something, please be specific.
Well, for one, Lambdas are desugared into methods, not anonymous classes. Early on they used anonymous classes because it was convenient but that wasn't the final translation strategy. http://cr.openjdk.java.net/~briangoetz/lambda/lambda-transla...
Re: An Opinionated Guide to Modern Java Development, Part 1
#358Earlier quoted context omitted.
He knows what he is talking about & his description matches the explanation by Brian Goetz. So unless I'm missing something, please be specific.
Well, for one, Lambdas are desugared into methods, not anonymous classes. Early on they used anonymous classes because it was convenient but that wasn't the final translation strategy. http://cr.openjdk.java.net/~briangoetz/lambda/lambda-transla...
1. A method in its parent class. 2. An invokedynamic instruction at the call site.
The invokedynamic instruction calls LambdaMetafactory, which compiles an anonymous class at runtime that calls method #1. So the only benefit of using invokedynamic is fewer class files, by deferring generating them until runtime.
Re: An Opinionated Guide to Modern Java Development, Part 1
#359Earlier quoted context omitted.
Well, for one, Lambdas are desugared into methods, not anonymous classes. Early on they used anonymous classes because it was convenient but that wasn't the final translation strategy. http://cr.openjdk.java.net/~briangoetz/lambda/lambda-transla...
My impression from the openjdk code is that each lambda generates: 1. A method in its parent class. 2. An invokedynamic instruction at the call site. The invokedynamic instruction calls LambdaMetafactory, which compiles an anonymous class at runtime that calls method #1. So the only benefit of using invokedynamic is fewer class files, by deferring generating them until runtime.
Re: An Opinionated Guide to Modern Java Development, Part 1
#360> In this example, Java is rather annoying, especially when it comes to testing the type of a message with instanceof and casting objects from one type to another. Using instanceof is an antipattern 99% of the time, easily avoided with proper API design. In this case a simple enum type would help with appropriate getType() method on the event; or a polymorphic event API with dedicated method types for each event (Lif…
Agree that instanceof is wrong and discredits the article. I'm not sure if this is what you meant, but here is how polymorphism along with the double dispatch pattern would work: NaiveActor#handleLifecycleMessage will need to delegate to the event subclass, which will in turn select the appropriate method on NaiveActor. Example of subclass of LifecycleMessage: class ExitMessage implements LifecycleMessage { @Override…
What I'm describing is a marker interface for eventing, with specific subtype APIs:
interface LifecycleListener { }
interface StartListener extends LifecycleListener {
void onStart(Foo f);
}
interface ExitListener extends LifecycleListener {
void onEnd(Foo f);
}
along with a single registration method (perhaps a LifecycleObservable API, or in a class also offering event-firing methods): Disposable addLifecycleListener(LifecycleListener l)
The benefits to the client code are numerous: clarity (dedicated methods for events), declarative code ('implements' section documents interactions), performance (no dispatching in client code).[Note, Disposable here represents a dispose() function to deregister the listener, avoiding the classic pair of void register/deregister methods. Often I find void methods represent a missed opportunity ... wishing Java was more like Smalltalk here]
The service side has to jump through some hoops to efficiently dispatch, using class equality or instanceof at registration time to pre-select listeners. This code could certainly use pattern-matching but personally I think it would look identical. If anything, I'm glad that pattern-matching isn't available in this case, to at least alert framework devs to the problem and not push it off to tons of switching on the client.