Java: Missing Features
infoq.com
infoq.com
Long story short: keep the traditional getters and setters but have just a byte[] field to store the object state. For example If you need just the date (without the time) you can store it in 2 bytes, say 7 and 8, and in getDate() method you do
public Date getDate() {
int day = bytes[8] * 256 + bytes[9]
return new Date(day * MILLIS_PER_DAY);
}
Some of the improvements are amazing* Auto-Properties - Get rid of all those ugle getters and setters cluttering up POJOs
* Object and Collection Initialisers - https://msdn.microsoft.com/en-us/library/bb384062.aspx
Unless someone else can help me, I think this is really bad advice for a C# developer.
Nomenclature schmomenclature.
They're variables with object scope.
There's a free plugin that adds Lombok support to Intellij. You will be able to use getters/setters/builders etc. as if they were compiled.
JVMLS 2015:
https://www.youtube.com/playlist?list=PLX8CzqL3ArzUo2dtMurvp...
Technical Keynote at JavaOne 2015
https://www.oracle.com/javaone/on-demand/index.html
Of course, first we still need to get Java 9.
And then when Java 10 with value types, reiffed generics, new FFI API, long Arrays is available, one can write blog posts about being forced to use Java 7 with these missing features on Android.
Run-time visible generics are pretty important because it lets us avoid boxing everything. In .NET, they don't have this problem, and as a result primitive dictionaries are ~17x faster [0]. Java folk wisdom seems pretty accurate to me in this case.
Interestingly, specialization can be done at compile-time and doesn't necessarily have to be a runtime feature. Here's a Scala compiler plugin doing that: http://scala-miniboxing.org/
It's neither according to the usual (C++-inherited) lingo where specialisation is the userland override of generics reification. Refinement may be a better term for what the article is talking about (runtime-optimised instances without reified types).
And refinements should already be doable in java today with no static type information, Pypy does it with list strategies, I expect Objective-C's hidden classes could also enable it (though I'm not aware of such a use).
> Interestingly, specialization can be done at compile-time
That's where they started...
However, IntelliJ, Java8 Streams, and Google Guava made the process tolerable.
I've grown to begrudgingly tolerate the weak Generics support, but the one thing absolutely still drives me insane is that I cannot have a method overload for a different generic parameter
i.e.
public void do(List<ABC> abcs);
public void do(List<DEF> defs);
FFS Java, come on. (Yes, I know, type erasure, it's still humiliating)nope.
Honest question: is there ever an acceptable case for having such a long String in memory?
Structural typing would really go against the grain of the language, and i have a very hard time believing it would actually be useful. What method name is currently widely used with the same semantics across many classes, without being specified by an interface or base class? I can't think of one. There used to be close(), but that's been dealt with. Are there others?
Collection literals seem like a poor idea when there are so many different collection implementations. If i say:
List<Integer> list = {1, 2, 3};
What kind of list do i get? ArrayList, as that's the usual go-to? A foot-shooting opportunity for anyone doing concurrent programming! And a frustrating missed chance for anyone with a functional bent who would prefer an immutable list. Moreover, it seems unnecessary when you could easily just add constructors or factory methods like: List<Integer> list = new ArrayList(1, 2, 3);
List<Integer> list = ArrayList.of(1, 2, 3);
Which leave the choice in the hands of the programmer for only a minimum of extra syntax.Maps are a bit harder, because you need a way to describe pairs. In most projects i work on, i end up creating some helper methods that let me write:
Map<String, Boolean> map = map(entry("Java", true), entry("Go", false));
And i wish there was a better syntax for that.Something like algebraic data types would be good, though. You can already implement un-extendable classes using mild hacks:
public abstract class Shape {
private Shape() {}
public static class Circle {
public static Circle of(int radius) {
return new Circle(radius);
}
public final int radius;
private Circle(int radius) {
this.radius = radius;
}
}
public static class Rectangle {
public static Rectangle of(int width, int height) {
return new Rectangle(width, height);
}
public final int width, height;
private Rectangle(int width, int height) {
this.width = width;
this.height = height;
}
}
}
Because the constructors are all private, so putative subclass can't call them. But you don't get pattern matching, and of course it's all rather verbose.There are various madmen out on the edge of town trying to create terse approaches to this by meddling with forces beyond mortal knowledge:
https://github.com/poetix/mtuples
But i can't see that going mainstream.
ImmutableMap.of(Key, Value, Key, Value...);
For ones with more than 4 values you will need:
ImmutableMap<String, Integer> WORD_TO_INT = new ImmutableMap.Builder<String, Integer>() .put("one", 1) .put("two", 2) .put("three", 3) .build();
It's not hard to do slightly better (IMHO!), though:
public class MapBuilder<K, V> {
public static <K, V> MapBuilder<K, V> with(K key, V value) {
return new MapBuilder<K, V>().and(key, value);
}
private List<Map.Entry<K, V>> entries = new ArrayList<>();
public MapBuilder<K, V> and(K key, V value) {
entries.add(new AbstractMap.SimpleEntry<>(key, value));
return this;
}
public Map<K, V> build(Map<K, V> map) {
for (Map.Entry<K, V> entry : entries) {
map.put(entry.getKey(), entry.getValue());
}
return map;
}
public Map<K, V> build(Supplier<Map<K, V>> mapSupplier) {
return build(mapSupplier.get());
}
}
Which lets you write: Map<String, Boolean> map = with("Java", true).and("Go", false).build(new HashMap<String, Boolean>());
Map<String, Boolean> map2 = with("Java", true).and("Go", false).build(Map::new);
I don't have Java 8 on the machine i'm on right now, so apologies if the second example doesn't compile; it might need more manifest types on it.- Collection and map literal.
- Value type.
- Multiple return values.
- Destructure.
- Pattern matching.
honest question - what would be real added value compared to dedicated wrapper type holding all you need for return?
2. Tuples support pattern matching.
3. For simple cases the return type is clearer, no need to dig up another class declartion to figure out what the field types are.
(int, float, float) calcPosition(...) {
...
return (type, x, y);
}
var (type, x, y) = calcPosition(...);
if (type)
move(x, y);
or var (int type, float x, float y) = calcPosition(...);
I would prefer the first case with automatic type inference.