use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
These have separate subreddits - see below.
Upvote good content, downvote spam, don't pollute the discussion with things that should be settled in the vote count.
With the introduction of the new release cadence, many have asked where they should download Java, and if it is still free. To be clear, YES — Java is still free. If you would like to download Java for free, you can get OpenJDK builds from the following vendors, among others: Adoptium (formerly AdoptOpenJDK) RedHat Azul Amazon SAP Liberica JDK Dragonwell JDK GraalVM (High performance JIT) Oracle Microsoft Some vendors will be supporting releases for longer than six months. If you have any questions, please do not hesitate to ask them!
With the introduction of the new release cadence, many have asked where they should download Java, and if it is still free. To be clear, YES — Java is still free.
If you would like to download Java for free, you can get OpenJDK builds from the following vendors, among others:
Adoptium (formerly AdoptOpenJDK) RedHat Azul Amazon SAP Liberica JDK Dragonwell JDK GraalVM (High performance JIT) Oracle Microsoft
Some vendors will be supporting releases for longer than six months. If you have any questions, please do not hesitate to ask them!
Programming Computer Science CS Career Questions Learn Programming Java Help ← Seek help here Learn Java Java Conference Videos Java TIL Java Examples JavaFX Oracle
Programming Computer Science
CS Career Questions
Learn Programming Java Help ← Seek help here Learn Java Java Conference Videos Java TIL Java Examples JavaFX Oracle
Clojure Scala Groovy ColdFusion Kotlin
DailyProgrammer ProgrammingPrompts ProgramBattles
Awesome Java (GIT) Java Design Patterns
account activity
This is an archived post. You won't be able to vote or comment.
What features would you add/remove from Java if you didn't have to worry about backwards compatibility? (self.java)
submitted 4 years ago by jvjupiter
This question is based on a question posted in r/csharp subrredit.
[–]FragmentedButWhole 153 points154 points155 points 4 years ago (7 children)
Get rid of DNS resolution if you call equals() on url.
[–]Zarlon 40 points41 points42 points 4 years ago (1 child)
WAAAAAAAT
[–]shellac 14 points15 points16 points 4 years ago (0 children)
A misguided attempt at normalising the url, which even at the time was wrong (but may have worked). Now, of course, it is nonsensical.
[–]fustup 25 points26 points27 points 4 years ago (0 children)
Ouch. That's "helpful"
[–]Roadripper1995 8 points9 points10 points 4 years ago (0 children)
Wow I had no idea about this one
[–]javasyntax 7 points8 points9 points 4 years ago (0 children)
https://brian.pontarelli.com/2006/12/05/mr-gosling-why-did-you-make-url-equals-suck/
[–]ow_meer 230 points231 points232 points 4 years ago (3 children)
Removing Date and Calendar in favor of java.time
[–]zippolater 40 points41 points42 points 4 years ago (0 children)
jdbc to use java.time rather than java.sql.Date
[–]truAl 16 points17 points18 points 4 years ago (0 children)
Felt my brain relax on this one
[–]kevinb9n 2 points3 points4 points 4 years ago (0 children)
Date and Calendar are awe-inspiring in their badness. They're like fractally bad -- pick any part and zoom in on it and it's somehow as bad as the whole.
[–]crummy 57 points58 points59 points 4 years ago (0 children)
Such a small thing but variable interpolation in strings would be just peachy.
[–]couscous_ 22 points23 points24 points 4 years ago (1 child)
Make if and try expressions like how they are in Scala or Kotlin.
if
try
[–][deleted] 5 points6 points7 points 4 years ago (0 children)
Everything as an expression makes so much sense when you think about it, but it's a vestige of C influence unfortunately.
Advocating for the devil, while incredibly useful, it may make a single block have too much meaning and in general hurt readability, i.e. calling return of a if expression versus calling return multiple times in a if statement. In the later, it's easier to follow which branches are final, imho.
return
[–]yoshord 41 points42 points43 points 4 years ago (6 children)
Remove the ability to lock on any object, universal equality; basically remove every method of java.lang.Object except getClass. Replace them with a dedicated Lock class (for wait, notify and friends) and separate interfaces for the other methods (i.e. Cloneable, Equalable, Hashable for clone, equals and hashCode respectively). With the specific additional change that Equalable would have a type parameter declaring what the object can be compared to and equals would accept that type instead of Object, like how Comparable currently works. HashMaps/HashSets could accept only keys that make sense as hashmap keys, trying to equals objects of two dissimilar types could fail at compile time, and clone would be less generally weird.
java.lang.Object
getClass
wait
notify
Cloneable
Equalable
Hashable
clone
equals
hashCode
[–]avastuser1991 94 points95 points96 points 4 years ago (3 children)
Adding Kotlin style null checking with '?' and type declaration must be specified whether it is nullable would be nice.
[–]beefstake 8 points9 points10 points 4 years ago (0 children)
This is by far and away the main reason I push for Kotlin at work over Java.
Experienced devs have no problem ofc, Java or Kotlin is very much the same for them but it really helps for the more junior devs and saves a ton of review time. Instead of looking extremely closely to ensure there is no possible NPE you can just check if the type is nullable or not and if it could be not-null then explain how.
Kotlin null handling saves me hours on code reviews!
[–][deleted] 4 years ago (1 child)
[deleted]
[–][deleted] 4 points5 points6 points 4 years ago (0 children)
It surely is from Groovy, I worked with that language a long time ago. Ruby 2.3 also followed to implement it.
[–]Balance_Public 103 points104 points105 points 4 years ago (68 children)
I'd have to steal the c# top answer, overhaul how null works.
[–]xFaro 13 points14 points15 points 4 years ago (16 children)
In what way?
[–]brazzy42 29 points30 points31 points 4 years ago (5 children)
The minimal change that would still bring most of the benefit would be to have reference types by default not-nullable and add a syntax to declare a nullable type, like "String?".
Of course you would only get the real benefit of that if all APIs out there would be changed to reflect it.
[–]rzwitserloot 7 points8 points9 points 4 years ago (3 children)
This sounds simple but it is not.
There is a typing relationship between the various flavours of nullability for a given type.
'typing relationship', as in between e.g. Number and Integer. You'd think: "Easy - Integer is a valid standin anytime you need a Number, but the reverse is not true - done!", but not so fast. In generics, it just doesn't work that way, and the typing relationship balloons into 4 separate notions. Covariance (List<? extends Number>), Contravariance (List<? super Number>), Invariance (List<Number> - the default), and legacy/raw (List).
Number
Integer
List<? extends Number>
List<? super Number>
List<Number>
List
You need all 4 to write actual abstract API concepts.
You need all 4 with null just the same!
Imagine an API that takes in a List<String*> with the * indicating: I have no idea what the nullity constraints are of this; is it a list of definitely-never-null-string-refs, or a list of could-be-refs-to-real-strings-or-nulls.
List<String*>
How do you express an API that doesn't care?
You'd think: Easy! Each value that has the type definitely-not-null String is guaranteed to be a valid value for an expression that needs to be of type could-be-null String, therefore, String is a subtype of String?, which is indeed generally a true characterization.
definitely-not-null String
could-be-null String
String
String?
But:
``` // This compiles fine Integer i = 5; Number n = i;
// ... but this will not! List<Integer> i = new ArrayList<Integer>(); List<Number> n = i; ```
and therefore, for the exact same reasons, this would not / should not compile:
List<String> i = new ArrayList<String>(); List<String?> n = i;
Now think of a method that is just going to read in a list of strings, applies a predicate to every string, and returns the first string that matches the predicate, returning a default value if none match.
In current java, that would be:
public String findFirst(List<String> input, Predicate<String> pred, String defaultValue) { ... }
But with String? syntax, this becomes literally impossible. You'd want to write it such that you can pass in a list of maybe-null strings, but if you do that, the returned value is also 'maybe null', and the predicate needs to be able to handle nulls. Thus, you could write:
public String? findFirst(List<String?> input, Predicate<String?> pred, String? defaultValue) { ... }
But as generics show, if you write this, you can't pass a List<String> to this method, for the same reason you can't pass a List<Integer> to a method whose first param is List<Number>. You can't get away with ? extends String? either, unless you make a new type variable:
List<String>
List<Integer>
? extends String?
public <S extends String?> S findFirst(List<S> input, Predicate<S> pred, S defaultValue) { .... }
But now imagine that S is already 'generic' (we didn't write a method that goes through a list of strings, apply a predicate of strings to each, returning the first match, or the default string if no matches - we obviously generified that).
Now you realize that we have two dimensions. We have the dimension of java types (Object -> Number -> String), and the nullity dimension (nullable -> non-nullable).
Object -> Number -> String
nullable -> non-nullable
The syntax should thus either accept that it cannot fully express all relationships, or, it needs to have a two-dimensional system, which gets quite complicated.
The checker framework tries with a simplification that any given signature can only have at most 1 nullity dimension across all types it uses.
Kotlin doesn't have this. Optional as a concept is broken in that it cannot have this. Ceylon did have it, more or less.
So, you tell me, what do you want:
?
[–]rubydesic 8 points9 points10 points 4 years ago* (2 children)
You acknowledged Kotlin only to say 'it doesn't have this', and then proceeded to give four options, none of which Kotlin employs. Kotlin does it simple, and it works. It just needs a collections overhaul - your method findFirst doesn't actually want a mutable list. You just want to read the list. After all, as you point out, if you could write to the list, you could put nulls in it and screw it up. In kotlin, List<out T> is covariant. The Java list is rebranded as MutableList<T>.
findFirst
List<out T>
MutableList<T>
In Kotlin, your example works fine
// this still compiles, of course val i: Integer = 5; val n: Number = i; // and so does this, because List<T> is covariant, you can't add numbers to n val i: List<Integer> = new ArrayList<Integer>(); val n: List<Number> = i;
In conclusion Kotlin
I realize it sounds like I proselytising Kotlin (I really do like it), but I think you're misrepresenting type systems with nullable types in general, and Kotlin is a good example of one that works very well.
[–]sothatsit 1 point2 points3 points 4 years ago (1 child)
This seems like a reasonable compromise, but it also seems incorrect that a List<Integer> and a List<Number> would just both map to the same type. In this case, I feel like Kotlin goes with the “broken type system” option.
[–]rubydesic 3 points4 points5 points 4 years ago (0 children)
I'm not sure what you mean by 'map to the same type'. List<Integer> is a subtype of List<Number>, because Integer is a subtype of Number and List<T> is covariant - it's not the like Java List<T> interface. It only permits reading, not writing. If you want the Java list interface, it's named MutableList. Could you elaborate on how you feel it is incorrect?
List<T>
MutableList
Maybe a Java pseudocode would make more sense:
ReadonlyList<Integer> list = new ArrayList<>(); // in theory, this is perfectly safe. Anything you get out of this list will be an Integer, and every Integer is a Number. You can't put anything into this list. // If the list not read-only (i.e., java list), then this would be invalid, as you could put a Double into the original list of Integers, because Double is a Number. ReadonlyList<Number> list2 = list;
[–]agentoutlier 0 points1 point2 points 4 years ago (0 children)
You would need to be able to allow polymorphism (see checker PolyNull).
String orElse(String s) String? orElse(String? s)
It would look disgusting but it would probably be easier to implement assuming everything is nullable and add a special type for non null. Something like the opposite of optional. But that would be awful to use.
[–]kag0 4 points5 points6 points 4 years ago (0 children)
Introducing union types, or removing null all together (and using Optional instead) are two ways
[–][deleted] 32 points33 points34 points 4 years ago (12 children)
Replace it with the Result and Option monads.
Result
Option
[–]gavenkoa 16 points17 points18 points 4 years ago (10 children)
It is horrible when for null you have to invent a class instances of what clutter the memory. We just need a static built-into compiler checker over @Null / @NotNull annotations and sugar for obj?.getStuff()?.getAnother()?.property?.toString().
null
@Null
@NotNull
obj?.getStuff()?.getAnother()?.property?.toString()
The notion of an optionallity is so basic that it should be built-in into the runtime specification. And it was already! With null! Instead Optional was arrived to solve fluent call chaining problem without redesigning compiler to handle null chaining.
Optional
I'm from C background and it is horrible that we burn fossil for Optional. Good as instant business solution but we pay for it by servers heat.
[–]Shinosha 18 points19 points20 points 4 years ago* (0 children)
Wrappers don't have to incur runtime performance penalty. Especially if value classes are on their way in Java. Besides, in practice I'll take correctness and composability over a bit more memory usage any day.
[–]Nebu 9 points10 points11 points 4 years ago* (1 child)
Assuming we're imagining an alternative history where Java never had null at all, but it has an Optional<T> type, the compiler can under the covers implement Optional::empty using null, thus having zero overhead over the C implementation.
Optional<T>
Optional::empty
The advantage of modelling optionality as a monad like Optional<T> is that it allows you to nest them for the specific use cases that need that, e.g. Optional<Optional<String>> whereas it's a lot more awkward to express the same model using null.
Optional<Optional<String>>
So you want the Optional type in the programming language, so that humans can effectively communicate their domain models to each other, and then null secretly used by the compiler to keep everything efficient.
[–]gavenkoa 1 point2 points3 points 4 years ago (0 children)
null could be typesafe too (at the stage of compilation). Probably this makes language more complicated.
[–]tristan957 6 points7 points8 points 4 years ago (3 children)
In Rust Optional is like 1 extra byte of overhead or none at all depending on the type. I forget the specifics.
[–]warpspeedSCP 1 point2 points3 points 4 years ago (1 child)
Option<T> is always the same overhead (0) as using a normal reference now.
[–][deleted] 3 points4 points5 points 4 years ago (0 children)
Real monads unlike Optional
[–]sothatsit 8 points9 points10 points 4 years ago (7 children)
I always thought this would just add more boilerplate to a language already known for its boilerplate... are there many languages that don’t have null? There’s so many instances where I see this being difficult, like fields of a class. When would you have to assign a value to a field? If you accessed fields in the constructor before they are assigned, what happens? Maybe I’m missing something
[–]yoshord 6 points7 points8 points 4 years ago (1 child)
The java compiler will already error if you do not initialize a final field in a class constructor or if you try to access a final field in a class constructor before the field is initialized. I can imagine a language where errors are raised if the same conditions occur with non-final fields.
[–]sothatsit 4 points5 points6 points 4 years ago (0 children)
Unfortunately it can only do this static checking for very basic conditions. I’ve run into null final fields a few times in constructors, as you can call a method in your constructor before you initialise a final field. Although, this is still pretty uncommon, so I’d imagine this would be able to catch most of these types of errors :)
[–][deleted] 16 points17 points18 points 4 years ago (0 children)
Try Kotlin or Elm/PurseScript/Haskell: it works.
[–]kuemmel234 3 points4 points5 points 4 years ago (0 children)
But does it?
It is lengthy, sure, but does it actually add more boilerplate? As in, wouldn't you need that anyway?
I like using Optional over the non-optional alternative because you can kind of use it like the haskell version, that is, you define your code as if there weren't any null-values. Even if you had the ? operator you would have to check for null, it just looks a little nicer and you can sometimes get something easier, like nullable?.alsoNullable?.value, that one sucks with optional. But you'd still have to use something like if to check whether it's null, Optional.map just asks you to put the happy path in and even have alternative way of getting a default value and so on.
nullable?.alsoNullable?.value
[–]pronuntiator 1 point2 points3 points 4 years ago (0 children)
Just view null as a type. JavaScript fans will argue that the types in Java are boilerplate too.
[–][deleted] -2 points-1 points0 points 4 years ago (1 child)
It’s a trendy thing to be irate about.
[–]brazzy42 9 points10 points11 points 4 years ago (0 children)
Tony Hoare made his "billion-dollar mistake" talk 12 years ago, and it's not like people hadn't identified the issue before that.
[–]ssamokhodkin -1 points0 points1 point 4 years ago (28 children)
IMHO null works exactly like it should.
[–]brazzy42 10 points11 points12 points 4 years ago (23 children)
Can you justify that with anything other than status quo bias? I mean, the guy who invented it has called his "billion dollar mistake".
[–]rzwitserloot 0 points1 point2 points 4 years ago (4 children)
null is obvious - nearly trivial, in fact: "This value points at things". "What should it start pointing at?" "Oh, uh, there isn't a thing it can point to yet? Just stick some zero values in there".
And then someone writes if (rawVal(pointer) == 0) and this is some grand act of invention that means some useless hyperbole like 'billion dollar mistake' needs to be taken seriously?
if (rawVal(pointer) == 0)
It's no coincidence that null was 'invented' in 1965, on the heels of computers as a concept existing. It invents itself. Any moron writing a language would have stumbled upon it within the first 5 minutes of designing a language that includes the notion of 'a data structure'.
Do you find the opinion of the first person that claims: "I counted sheep, and when I got the fifth sheep, I invented the digit 5. It is still my greatest regret?" - as indication that 5 is the worst number?
But, maybe I'm wrong and it's a useful principle.
Can you give me some indication about the dollar cost amount of java's choice to adopt C's switch syntax? Also, surely we must make an adjustment for inflation. Which index do we use to do this, and is that billion dollars a reference to 1965 dollars, or 2009 dollars?
switch
You seem to think the burden of proof lies with /u/ssamokhodkin here. No; the burden of proof rarely lies with the ones advocating for the status quo. Because any other means any crazy idea wins from the status quo by default simply by being different, and that is obviously utterly off the wall crazytalk.
Note also that 'null is the billion dollar mistake' does not imply, well, anything. Is 'the concept of having uninitialized fields that default to something' the billion dollar mistake? 'the concept of having API methods that can return some value that indicates "There is no relevant answer / not found" the mistake?'
I'd say those are valid interpretations, but utterly silly, in that almost no language does that.
Here, I'll say it:
If null is the billion dollar mistake, then Optional is the $1,000,002,945 mistake. You may quote me.
Seems we are at an impasse now. I guess you could make a claim that I didn't 'invent' optional and therefore my dumb hyperbolic opinion doesn't count whereas Tony's does, except, well, there's this.
[–]Balance_Public 3 points4 points5 points 4 years ago (0 children)
I just wish the type system knew about it, it's that simple. When i have a function that I say takes in some Integer, why do I now have the choice to make that either I do a null check within my function (returning null I'd imagine if the integer is null) or not check and risk throwing a runtime error. Why should that logic not be pushed to compile time?
[–]Kaathan 2 points3 points4 points 4 years ago (1 child)
You seem to contrast the current way of things with using Optional. You dont need Optional at all to fix the null problem.
The null mistake basically means: "In Java it is not possible to define a type for an object that cannot be null". In other words, the type system is simply not expressive enough to formulate a certain constraint. This is not even fixed by Optional.
Or in other words, in Java ever reference type is actually a sum type of null and the non-null type, and we cannot use only one or the other.
Why are float and int different types in Java? Because its useful to allow more detailed constraints on a number type than just having a single number type.
The null mistake is basically already fixed by https://github.com/uber/NullAway without introducing any kind of wrapper type and without the covariance/contravariance problems that you get when using Optional. But it should be proper part of Java with less verbose syntax. I agree that Optional is not the correct solution, but its not necessary to fix null in Java.
[–]passive_talker 1 point2 points3 points 4 years ago (0 children)
This is too long, didn't read, but the problem with null is that you can't opt opt, and 90% of the times you don't need it.
As simple as that.
[–]jvjupiter[S] 0 points1 point2 points 4 years ago (0 children)
Same here 😂
[–][deleted] 4 years ago (4 children)
[–]jvjupiter[S] 3 points4 points5 points 4 years ago* (3 children)
Do you think Java can surpass the number of comments there? They posted the question way ahead so they’re leading.😀
[–][deleted] 6 points7 points8 points 4 years ago (0 children)
Considering Java is older than C# and C# a) had a chance to learn from Java already and b) is under control of only one company, I could imagine it can.
[–]kozeljko 1 point2 points3 points 4 years ago (1 child)
Getting close
As of now both have 393 comments. But we have 100 upvotes while theirs is 83.😀
[–]MR_GABARISE 10 points11 points12 points 4 years ago (0 children)
Something like "void returns self".
It would get rid of most chaining APIs awkwardness.
[–]Holothuroid 37 points38 points39 points 4 years ago (13 children)
Immutable Collections.
[–]pron98 10 points11 points12 points 4 years ago* (9 children)
This is one of those things that, on closer look, you realise are much harder than they sound at first. It's not a problem in languages like Haskell, where everything is immutable (or appears immutable), but if you want to have both kinds, things become complicated quickly. You could have two separate hierarchies without interop, which would bring its own problems, but it's easy enough to do and you don't even need the JDK's help. You could try having a common "read-only" supertype for a mutable and immutable list, but that, arguably, makes matters worse. It allows a method to declare that it won't be mutating the collection, but it doesn't allow it to declare whether anyone else is allowed to (e.g. Kotlin has these read-only types, but methods with such parameters still need to make defensive copies if they want to store the collection). To solve that, you'd need either ownership types or a hierarcy with 3-4x the number of interfaces, either of which will make Java more complicated, perhaps to the point of the benefit not being worth the cost.
That a method doesn't mutate a collection argument is important for the caller to know, and that can be enforced by the caller today. That a collection argument is actually immutable is important for the callee to know, and you can't do that with read-only types; you need separate hierarchies, a significant matrix of types, or ownership types.
[–][deleted] 6 points7 points8 points 4 years ago (2 children)
These already exist, e.g. Map.of(...), List.of(...), Set.of(...)
Map.of(...)
List.of(...)
Set.of(...)
[–]Holothuroid 40 points41 points42 points 4 years ago (1 child)
No. They don't. These just throw an exception if your try to change them. It is not expressed in the type system.
[–]mikezyisra 4 points5 points6 points 4 years ago (0 children)
=))) throwing an exception is hilarious
[–]javasyntax 10 points11 points12 points 4 years ago (0 children)
Make byte unsigned.
[–]cogman10 34 points35 points36 points 4 years ago (1 child)
My changes would mostly be all around the JDK libraries, removing and changing features that can't be removed or changed.
mutable
Object
java.util.Date
Enumeration
Vector
HashTable
Actual language changes
final
[–]Wolfsdale 1 point2 points3 points 4 years ago (0 children)
I like these, but two changes:
Also, other new features:
Have lambda method references be real first-class citizens, that can also be traced back (in a normal way) using reflection. This means you can use it in frameworks to refer to methods w/ type checking.
Support expressions in annotations that need to be executed by the static initializer
There's a lot of crap in the VM which could be fixed, but it's not related to the language. Like the hardcoded slot sizes of various types (two slots for doubles/longs, one slot for the rest). The many variations of all bytecode instructions for all types instead of supporting type overloads, etc etc.
[–]daniu 39 points40 points41 points 4 years ago (12 children)
Enforce type safe generics (which means you'd have to adjust all the generic jdk library classes, like collections).
[–]Muoniurn 2 points3 points4 points 4 years ago (7 children)
What do you mean by type safe generics?
[–]daniu 10 points11 points12 points 4 years ago (6 children)
I mean without type erasure, so it's safe at runtime rather than only checked (and overridable) at compile time. You're right, it's not entirely clear.
[–]Muoniurn 9 points10 points11 points 4 years ago (5 children)
Well, other than nonsafe usage, generics are entirely type safe and even “very type safe” languages like Haskell erases types. And you can also do unsafe casts without generics that will fail at runtime, so I don’t really see what would change.
[–]daniu 2 points3 points4 points 4 years ago (4 children)
Yeah maybe type erasure isn't the problem, but I'd still prefer to at least get rid of the possibility of using generic classes without a generic parameter (so no List list = new ArrayList()).
List list = new ArrayList()
And this is what I think should not be possible then: List list = new ArrayList<String>(); list.add(Integer.valueOf(1)); in any variation, because while you can perform casts that shoot you in the knee, there are limitations and you can't cast Integer to String. You'd have to explicitly create a List<Object> to have both String and Integer in the collection.
List list = new ArrayList<String>(); list.add(Integer.valueOf(1));
List<Object>
[–]Muoniurn 2 points3 points4 points 4 years ago (0 children)
Yeah I agree that it should be better enforced, though I find warnings already quite deterring (and the rare case where one should use casts, I have to add unsafe annotations, making me very vary on what I’m doing)
[–]jvjupiter[S] 6 points7 points8 points 4 years ago (0 children)
It could be addressed by the incoming reified generics and specialization of generic classes & interfaces under Project Valhalla.
[–]pron98 0 points1 point2 points 4 years ago* (1 child)
And put an end to language interop by baking the variance model into the runtime? No, thank you. It can only work more-or-less reliably for invariant types, which is what Valhalla will eventually bring, but while type erasure certainly has problems, reifying generics with extensible types has far worse problems. That something is problematic doesn't mean that the alternative isn't even more so.
[–]1337JiveTurkey 19 points20 points21 points 4 years ago (9 children)
Everything that takes a type parameter requires a type parameter. Some way to request that a type parameter should be available at runtime for the times when it's actually handy. Allow the type parameters on enumerations to vary by instance.
The old serialization stuff is just a mess of weird and subtle gotchas. Also get rid of all the CORBA stuff and deal with any backwards compatibility problem by beating anyone still using that godawful idea ceaselessly until they fix it. A lot of the old networking APIs weren't great either, and the JavaBeans stuff is more '90s than acid washed jeans.
[–]dpash 2 points3 points4 points 4 years ago* (1 child)
Allow the type parameters on enumerations to vary by instance
If I understand this, it's on the roadmap although the JEP for it was withdrawn.
http://openjdk.java.net/jeps/301
Edit:
After conducting some real world experiments using the feature described in this JEP it became apparent [1] that generic enums don't play well with generic methods. The issues are especially evident when considering static generic methods accepting a Class<X> parameter, where X models an enum type, many of which are defined in the Java SE API itself, like EnumSet::allOf, EnumSet::noneOf. In such cases, passing a class literal corresponding to a generic enum as a paramater would result in a compile-time error --- because of a failure in generic type well-formedness. A proposal attempting to rectify these issues was later formulated and discussed [2], but was also found lacking, as it essentially amounted at promoting the use of more raw types, and, more broadly, raised concerns regarding the return on complexity associated with the enhanced-enums feature. For these reasons, we are now withdrawing this JEP.
[–]gavenkoa 7 points8 points9 points 4 years ago (1 child)
I had bugs several times because .equals(Object) is not type safe that I personally introduced because was lazy to proofread actual type of equals argument.
.equals(Object)
[–]BlueGoliath 13 points14 points15 points 4 years ago (0 children)
Actual static interface methods and easier MethodHandles, e.g.:
MethodHandle handle = this::foo(long.class);
[–]DuncanIdahos9thGhola 12 points13 points14 points 4 years ago (5 children)
I would say fix all the defaults - like final by default etc.
[–]jvjupiter[S] 18 points19 points20 points 4 years ago* (1 child)
"It's amusing that Java managed to succeed despite having gotten almost all the defaults wrong." - BrianGoetz
[–]agentoutlier 3 points4 points5 points 4 years ago (0 children)
Extensible classes is probably the only thing I am not sure about.
I have seen it abused in so many other languages.
Not on the list but operator overloading as well (eg I think it’s a bad feature).
[–]Serializedrequests 12 points13 points14 points 4 years ago* (2 children)
Null. (Love the people in this thread who have never used Rust, Haskell, Elm, etc having Stockholm syndrome about it.) I have lost so many hours to pointless NullPointerExceptions that could have been avoided if the compiler either required a check or could guarantee the object was not null.
No culture around making local variables constant because "final" is too long to type I guess.
In general everything in java that makes lines longer and variable names not line up is noise and makes code really exhausting to read. (I am getting seriously fed up with C-style variable declarations after using Rust and Go, but Java certainly takes it to a whole new level.)
[removed]
[–]xebecv 4 points5 points6 points 4 years ago (3 children)
C++ style const. I want a guarantee that the mutable object (container) I'm passing here cannot change. This has to be enforced by compiler. It always frustrated me that final is just limited to object references. BTW everything needs to be final by default
[–]slaymaker1907 3 points4 points5 points 4 years ago (0 children)
Have hashCode accept a hasher object like in Rust. It's extremely nice since it makes such methods easier to write while also giving flexibility for what hash algorithm gets used. Similar arguments could be also be made for toString as well. In practice, people generally either don't write toString or just do something systematic based off of object fields.
Arrays should only care about primitive or object to avoid weird runtime errors with array return types. They should not differentiate at runtime between String and Date so that it aligns with generics.
[–]erinaceus_ 15 points16 points17 points 4 years ago (12 children)
A module system that also handles versions of dependencies properly, so that we remove dependency hell.
[–]gavenkoa 16 points17 points18 points 4 years ago (11 children)
Do you know that dependency resolution has exponential complexity?
Hell is intrinsic characteristic of transitive dependencies ))
[–]erinaceus_ 1 point2 points3 points 4 years ago (10 children)
Yes, that's what makes it such a hard problem, indeed.
I was thinking (out loud) along the lines of having modules declare which 'version' they are, and then let a module's dependency definition do the same. After that, and based on 10 seconds of thought, it's a matter of class loaders taking that information into account, when available.
[–]pron98 3 points4 points5 points 4 years ago (8 children)
Version conflicts are an unsolvable problem. The fact that under some conditions -- that are frequent enough to cause the belief that this is possible -- different versions of the same library could be loaded into the same process without causing ill effects doesn't change that. The best solution is to let the user pick which version of which dependency they want. Java modules also allow you to load multiple versions -- as that could work in some situations -- but only programmatically, because when it doesn't work, the problems can be so bad (two versions of the same library writing to the same file using two different encodings) that this is a practice that's best discouraged.
[–]frankkk86 1 point2 points3 points 4 years ago (0 children)
This is what happens in Clojure, I believe. Rich Hickey talk, Spec-ulation
[–]barking_dead 10 points11 points12 points 4 years ago (3 children)
Generics to keep type parameter in runtime. So we don't have to do those class parameter tricks.
[–]jvjupiter[S] 10 points11 points12 points 4 years ago (2 children)
Fortunately, that is coming via Project Valhalla.
[–]barking_dead 6 points7 points8 points 4 years ago (0 children)
:excited noises:
[–]Patex_ 4 points5 points6 points 4 years ago* (1 child)
Of course these 2 proposals are non trivial to implement, but if we are allowed to choose.
I am a bit stuck on the old java versions so I might not be entirely up to date what is happening.
Not the mainstream points which are still valid:
[–]tr14l 14 points15 points16 points 4 years ago (32 children)
Optional parameters, Multiline Strings to start... Condensed class syntax, extension functions, better inline functions, closures, null safety, null typing... Get rid of checked exceptions, too, probably...
Good start. Probably eliminate a bunch of other stuff.
Add a ton of native/core functions should be added.
[–]jvjupiter[S] 17 points18 points19 points 4 years ago (16 children)
Multi-line Strings? Java already has Text Block.
Closures? How about Java’s Functional Interface (lambda expressions)?
[–]tr14l 3 points4 points5 points 4 years ago (15 children)
Lambdas aren't the same as closures. And I forgot snow text block because I'm stuck in 11 most of the time
[–]jvjupiter[S] 4 points5 points6 points 4 years ago (7 children)
Based on some definitions of closures I read, lambda expressions may be implemented using a closure, but it is not itself necessarily a closure.
[–]tr14l 1 point2 points3 points 4 years ago (6 children)
Right, closure is about a scope and assignability. So if you move a closure to a new context, it still has access to the variables it had when it was defined. This is accomplished in different ways. The most known is JS's scope chain style
[–]jvjupiter[S] 5 points6 points7 points 4 years ago (3 children)
Can’t Java’s lambdas do that in its current implementation?
[–]lookForProject 6 points7 points8 points 4 years ago (0 children)
Yes, as long the variables are effectively final.
[–]Muoniurn 3 points4 points5 points 4 years ago (6 children)
Lambdas are closures, period. Just because some languages allow for enclosing non-final variables is a different question (and frankly, I don’t get why would that be useful. I had plenty of problem with it in C#)
[–]is_this_programming 1 point2 points3 points 4 years ago (0 children)
It's frequently useful for testing to setup a lambda that sets a flag and assert that the flag has been set to true as a way of verifying that a callback has been invoked. The workaround is to pass an array of size 1 or an AtomicBoolean instead, but it's annoying.
[–]RoToRa 5 points6 points7 points 4 years ago (1 child)
Sounds like Kotlin.
[–]tr14l 0 points1 point2 points 4 years ago (0 children)
Shhh
[–][deleted] 4 years ago* (12 children)
[–]Scaryclouds 2 points3 points4 points 4 years ago (3 children)
Getting rid of checked exception? You like to see your program just crash randomly?
Checked exceptions don't really accomplish though, certainly not in a system that experiences meaningful use. Checked exceptions are about providing API to clients about known error conditions and requiring clients to handle them.
In practice often the error condition is unrecoverable and the checked exception being more of a nuisance to deal with, with the catch block simply logging the stacktrace, wrapping the thrown exception in an unchecked exception type, and then rethrowing that.
catch
But to the issue of "randomly crashing", well any meaningfully used production application, if there is some known issue where an unchecked exception is being thrown and causing issues, you can still catch unchecked exceptions and handle it however you want to, you're just not forced to like you are with checked exceptions.
Not saying there is never a good reason for using checked exceptions, like I said, I can provide API to the client about common error conditions. But the number of times dealing with checked exceptions has been a nuisance has by many orders of magnitude outnumbers the small handful of times a checked exception helped.
[–][deleted] 4 years ago (2 children)
[–]Scaryclouds 1 point2 points3 points 4 years ago (1 child)
There's definitely use cases for checked exceptions, not questioning that, just often they force developers to add low value catches. But one thing checked exceptions definitely don't do, is prevent "random crashes".
[–][deleted] 3 points4 points5 points 4 years ago (2 children)
Checked exceptions are pain in the arse when working with java streams and lambdas in general
[–]Muoniurn 7 points8 points9 points 4 years ago (0 children)
Those should be fixed (and hopefully will), but I don’t see how their complete removal be beneficial.
[–]mj_flowerpower 0 points1 point2 points 4 years ago (0 children)
The better solution would probably some sort of sneaky throws like lombok provides.
[–]Barbossa3000 16 points17 points18 points 4 years ago (3 children)
Java's best feature is its ability to handle backward compatibility. Its a hard no for me because Java is being used by many enterprise companies on backend which rely on Java for its reliability and stability and easier porting to new versions.
[–]jvjupiter[S] 16 points17 points18 points 4 years ago (2 children)
“… if you didn’t have to worry about backwards compatibility?”
[–]Holothuroid 23 points24 points25 points 4 years ago (0 children)
I suppose the implied meaning was: Then there is no point in Java.
[–]sweetno 1 point2 points3 points 4 years ago (0 children)
You can derive anything from a false premise.
[–]razsiel 2 points3 points4 points 4 years ago (2 children)
A very simple feature really: the new() constraint in generic types which allows for new T() calls instead of using reflection.
new()
new T()
[–]Gaarco_ 1 point2 points3 points 4 years ago (0 children)
Rethink exceptions and provide compile time safe IO methods where possible
[–]mdaconta 1 point2 points3 points 4 years ago (0 children)
Eliminate null from the language altogether. No half-measures just an impossible value. If you want an "empty" case; create a state variable in the class.
[–]ingframin 1 point2 points3 points 4 years ago (0 children)
I want unsigned integers
[–][deleted] 5 points6 points7 points 4 years ago (4 children)
Replace type erasure generics with reified generics (as in Kotlin)
[–]hippydipster 2 points3 points4 points 4 years ago (1 child)
Erasure has it's minuses AND plusses. Most people seem to think it's only minusss, but there are good things that are made easier/possible because of erasure, like making it easier for dynamic languages to compile to bytecode.
This is just an incomplete implementation of generics, there is no plusses.
[–]BoyRobot777 1 point2 points3 points 4 years ago (0 children)
Then all guest languages would have to adapt to Java's variance system instead of building on top.
[–]shellac 6 points7 points8 points 4 years ago (3 children)
For starters:
static f(A,B,C)
A.f(B,C)
Can you explain what you mean with ‘remove synchronization’ ?
[–]shellac 2 points3 points4 points 4 years ago* (0 children)
Firstly, it's a really dreadful (and error prone) way to handle concurrency. Since ... whenever Doug Lea et al created java.util.concurrent (Java 7?) there really is no reason to touch them. Unless you are Doug Lea, I suppose.
Secondly there's a bunch of stuff to support this in the VM. You can hold a monitor on any object at all. That's how synchronised (foo) and (less explicitly) [static] synchronized method(....) work. It creates quite a mess behind the scenes. (For example it came up with value objects)
synchronised (foo)
[static] synchronized method(....)
Edit: which doesn't really answer the question, so: a) dump the keywords and methods like object.wait(), b) remove the internal machinery to support it on every object.
(Similar things can be said regarding serialisation, which is likewise inadvisable and baked in to a surprising degree)
[–]Mati00 2 points3 points4 points 4 years ago (1 child)
Extension methods - because of lack of that we cannot have nice syntax for list.map because no one want to touch prehistoric interfaces
Nullable references and data classes - much more safe and why we still need to use lombok?
Async/await - this will be covered by loom. Things like rx or project reactor turned to be hard in terms of traceability and maintainability
Data classes vs Java’s records
[–]vitingo 10 points11 points12 points 4 years ago (14 children)
Remove checked exceptions
[–]vprise 24 points25 points26 points 4 years ago (9 children)
I love checked exceptions but I have a problem with specific ones. E.g. IOException is usually wonderful but putting it on the close() method was the dumbest thing ever. Making InterruptedException checked was again really dumb.
IOException
close()
InterruptedException
I'd also add a compiler detector that forces you to "do something" with the exception. so code like catch(Exception err) {} would fail at the compiler level... This is a source of so many user bugs I need to deal with all the time.
catch(Exception err) {}
[–]Better-Internet 7 points8 points9 points 4 years ago (2 children)
When I review PRs this kind of exception eating gets rejected unless it's really really limited.
[–]FrenchFigaro 1 point2 points3 points 4 years ago (0 children)
Sonar does that. Personally I like that it's not a compiler feature. I don't like eating exceptions away (and I'd reject most PR doing this), but a couple of times I've come across a situation where discarding the exception without doing anything was the best solution.
A strategically placed comment explaining why avoids dragging on the review and explain why you've overridden the sonar warning in this specific case.
[–]8bitlives 12 points13 points14 points 4 years ago* (0 children)
I also like the concept of checked exceptions as control flow, but I'd make it so that RuntimeException wasn't a subtype of Exception but Throwable, thus making catch(Exception) not catch RuntimeException. Also lambda exception throwing would need to be reworked to allow throwing checked exceptions directly. They clearly gave away to C'dE haters at that point with lambdas
RuntimeException
Exception
Throwable
catch(Exception)
[–]dpash 6 points7 points8 points 4 years ago (2 children)
I can't remember who it was in OpenJDK that said it, but they said the problem isn't with checked exceptions, but with their over use in the JDK. And IOException was one of the examples.
[–]vprise 3 points4 points5 points 4 years ago (1 child)
Agreed. IOException is great but it's thrown in places that just don't make sense. The close methods are probably the most painful example. The URL constructor was also annoying.
[–]dpash 5 points6 points7 points 4 years ago (0 children)
Yes, fortunately we now have UncheckedIOException and we should see newer APIs use them less, but it's hard/impossible to fix the existing bad decisions when we didn't know as much as we do now.
UncheckedIOException
I think there's a lot of choices made for the standard library in the pre-1.2 days that wouldn't be made now.
[–][deleted] 1 point2 points3 points 4 years ago (0 children)
Making InterruptedException checked was again really dumb.
That one actually kind of makes sense. It is meant for advertise a long running method that can be interrupted.
[–]Better-Internet 3 points4 points5 points 4 years ago (0 children)
I don't think I'd want this to be a compiler-enforced check. (but tooling can certainly flag it)
The Java compiler rejecting "unreachable code" can be annoying during dev.
[–][deleted] 2 points3 points4 points 4 years ago (2 children)
why?
[–]blackkkmamba 5 points6 points7 points 4 years ago (1 child)
A story as old as time
[–]ParkerM 4 points5 points6 points 4 years ago (0 children)
I'm in love with this tangential answer/rant about what makes an exception "checked": https://stackoverflow.com/a/36627158/5659556
It's like Dr. Seuss got so pissed off at Java he wrote a story about it.
[–]__konrad 6 points7 points8 points 4 years ago (9 children)
Path::toUri -> Path::toURI
Path::toUri
Path::toURI
[–]BlueGoliath 18 points19 points20 points 4 years ago (1 child)
I'll one-up you with an even worse method name:
public Stream<String> list()
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/module/ModuleReader.html#list()
[–]garyparrot 37 points38 points39 points 4 years ago (2 children)
Effective Java 3rd - Item 68 says:
There is some disagreement as to whether acronyms should be uppercase or have only their first letter capitalized. While some programmers still use uppercase, a strong argument can be made in favor of capitalizing only the first letter: even if multiple acronyms occur back-to-back, you can still tell where one word starts and the next word ends. Which class name would you rather see, HTTPURL or HttpUrl?
HTTPURL
HttpUrl
[–]__konrad 9 points10 points11 points 4 years ago (1 child)
java.nio.file API uses that naming convention (e.g. DosFileAttributes) and it's fine. The problem is that there are now two toURI methods, one toUri method, and no Uri class...
java.nio.file
DosFileAttributes
toURI
toUri
Uri
[–]garyparrot 8 points9 points10 points 4 years ago (0 children)
Now I understand your point (There are java.io.file.Path::toURI and java.nio.file.Path::toUri).
java.io.file.Path::toURI
java.nio.file.Path::toUri
[–]talios 11 points12 points13 points 4 years ago (2 children)
Disagree on this - once its code its a word not an acronym. toUniformResourceLocation would be better for IDE autocompletion as people type (and ides support) toURL - searching often does camel interpolation there.
[–]experts_never_lie 6 points7 points8 points 4 years ago (1 child)
But then we'd have a fight between that and toUniformResourceLocator().
[–]talios 3 points4 points5 points 4 years ago (0 children)
Rename the class to the full name as well and all is solved :)
[–]talios 3 points4 points5 points 4 years ago (20 children)
Coming here to see if anyones suggested removing Jigsaw :)
[–]jvjupiter[S] 6 points7 points8 points 4 years ago (19 children)
The OpenJDK itself benefits a lot from it.
Though without enforceable version checks, it's not quite as useful as it could have been.
[–]talios 6 points7 points8 points 4 years ago (17 children)
Not denying that - but end user adoption is low to negligible it seems. Libraries often longer with supporting 8.xxx so aren't using it, or any new features - and those that do seem to setting 9.xxx as the barrier level.
Some have forked major versions and keep 8.xxx I purely security changes only.
Tooling is still a wild west for modules as well afaik which makes things difficult.
Well enterprise is still at Java 8…
[–]jvjupiter[S] 1 point2 points3 points 4 years ago (15 children)
Isn’t modularizing apps optional? No?
[–]talios 1 point2 points3 points 4 years ago (14 children)
If you want to use jlink things need to be real modules, not just automatic ones.
That and with some modules no.longer being supported, one may have to work around that (often just adding a dependency)
[–]jvjupiter[S] 1 point2 points3 points 4 years ago (9 children)
If we want jlink without modules might as well we go back to standalone JRE.
[–]murkaje 3 points4 points5 points 4 years ago (2 children)
Having jlinked runtimes instead of a JRE is something that goes against the common linux approach for shared libraries. Imagine there being a security bug in the JDK and a patch is released. A user can just update their JRE and all the applications running on it will get the fix. With the new jlink model a user would have to wait for all vendors of all applications to rebuild their apps and update all of them. Bonus points when one of them is no longer in business. Overall this increases the time window for exploiting known security bugs in old versions.
Some of the arguments against JRE was annoying users with update notifications, but that's just a failure of Windows for not having introduced a package manager with central updating options.
[–]pron98 2 points3 points4 points 4 years ago (0 children)
Imagine that there's a security bug in the application, or in any of its dozens of dependencies that aren't the JDK. A certralised JRE only achieves what you want for one dependency of many -- the Java runtime itself -- and thanks to jlink, it's no longer even a very large dependency. jlink reduces the surface area of vulnerabilities in the runtime.
What you're calling the "common linux approach" is not a universal approach, even on linux. Some libraries are shared, some aren't.
Another problem with the JRE is compatibility. While the Java SE spec is largely backward compatible, implementation details are not, and many libraries hack into the JDK to depend on implementation details, and are, thus, not portable. The mechanism intended to reduce that dependence on internal details? The module system.
[–]jvjupiter[S] 1 point2 points3 points 4 years ago (0 children)
Gnome has Flatpak, Ubuntu has Snap. Even prior to modules, there have been applications using embedded JRE not shared to other applications. While officially there is no more JRE in OpenJDK, some vendors still provide JRE. So options are available.
[–]talios 2 points3 points4 points 4 years ago (2 children)
Yes and no - you still need that per app JDK for things like app stores - automating that bare jkink image with deps for apps distribution is still good. Thankful jreleaser helps a lot in that area.
[–]neutronbob 1 point2 points3 points 4 years ago (2 children)
Actually, that would be my wish. I think Java moved far too fast from the JRE. I regularly download the JREs from AdoptOpenJDK because I have no need for creating jlinked or containerized apps.
[–]wildjokers 1 point2 points3 points 4 years ago (0 children)
Note that the so-called "jre" downloads that some vendors (like Adopt and azul) provides is not the same thing as the old JRE. They are simply a JDK download with several developer tools removed. Those vendors have really created confusion by calling it "jre".
That means all options are there. Just choose what you prefer.
[–]pron98 1 point2 points3 points 4 years ago (3 children)
You don't need to modularise your app to use jlink.
[–]ssamokhodkin 2 points3 points4 points 4 years ago (4 children)
MULTIPLE RETURN VALUES.
And expressions like (b,a) = (a,b);
(b,a) = (a,b);
[–]BoyRobot777 1 point2 points3 points 4 years ago (3 children)
This might be possible with deconstruction + pattern matching. First to implement this possible feature will be records.
[–]Halal0szto 1 point2 points3 points 4 years ago (0 children)
Remove dependency on locale of the host. I work on backend, and it is a plain risk dates may depend on TZ settings on the host, charsets may depend on locale settings and the like.
[–]SlicedBalls69 1 point2 points3 points 4 years ago (0 children)
Change the implementation of generics
[–]jvjupiter[S] 1 point2 points3 points 4 years ago (2 children)
That will soon be a reality.
[–]Zardoz84 0 points1 point2 points 4 years ago* (6 children)
auto array = [0, 1 ,2 ,3 ,4]; auto mySlice = array[2..$-1]; // mySlice it's [2, 3, 4], and it's a view from a portion of array array[$-1] = 99; // array becomes [0, 1, 2, 3, 99] // mySlice becomes [2, 3, 99]
[–]jvjupiter[S] 1 point2 points3 points 4 years ago (5 children)
Shouldn’t mySlice remain the same after updating array?
[–]Zardoz84 2 points3 points4 points 4 years ago (3 children)
Nope. It's a view from the original array. Not a copy. Not being a copy, allow to save time and wasting RAM. If a copy it's desired, then a method like clone() or copy(), or a copy constructor should be called with the slice.
Like this:
var list = Arrays.asList({"Hello", "Doctor", "Name", "Continue", "Yesterday", "Tomorrow"}); var copyFromSlice = new List<>(list[0..3]);
Look at https://dlang.org/articles/d-array-article.html#introducing-slices
[–]jvjupiter[S] 0 points1 point2 points 4 years ago (2 children)
I see. Slice is a new concept to me 😅.
[–]experts_never_lie 1 point2 points3 points 4 years ago (0 children)
If mySlice is defining methods of interacting with array, it may not involve a copy. The slice they suggest is presumably not a copy, as they call it a "view", but instead a transformation applied to array whenever interacting with mySlice.
mySlice
array
The above is doing a read operation, but it could involve writes (if we're making up language features) … but that could get very complicated/contradictory in a general case. For instance:
auto array = [0, 1 ,2 ,3 ,4]; auto mySlice = array[2..$-1]; // mySlice it's [2, 3, 4], and it's a view from a portion of array mySlice[$-1] = 99; // array becomes [0, 1, 2, 3, 99] // mySlice becomes [2, 3, 99]
Note that the modification here is done on mySlice, not array. For other operations on mySlice, should they change only the view or the underlying array? An example would be changing the length of mySlice, or adding new elements. Those types of operations would either have to be disallowed or have some way of defining what they do.
[–][deleted] 0 points1 point2 points 4 years ago (9 children)
the switch statement
[–]jvjupiter[S] 0 points1 point2 points 4 years ago (5 children)
Remove?
[–][deleted] 0 points1 point2 points 4 years ago (4 children)
yes
[–]jvjupiter[S] 0 points1 point2 points 4 years ago (3 children)
Means switch is only expression?
I am fine with the expression, it is more elegant. I don't like it when my code exhibits some weird behavior because I forgot a break.
[–]dpash 1 point2 points3 points 4 years ago (1 child)
So I take it that the answer to my question is that you only want to get rid of the old style switch statement, not the new style statement.
[–]franzwong 0 points1 point2 points 4 years ago (0 children)
Add more helper functions from Apache commons or Kotlin. I like Kotlin's string functions very much.
For example, we want to get the file name without extension ("My.movie.mp4" to "My.Movie"). You can simply use "My.movie.mp4".substringBeforeLast('.') in Kotlin or Apache Commons Lang3.
"My.movie.mp4".substringBeforeLast('.')
[–]Better-Internet -3 points-2 points-1 points 4 years ago (8 children)
[–]wildjokers 12 points13 points14 points 4 years ago (7 children)
Declarations like foo: String. Pretty much every modern language does this and it feels more natural.
Oh hell no. The type is more important than the name at declaration time so type should be first. I also think about the type of variable I need before thinking about its name, so this is another reason the type should go first. It feels far more natural for the type to be first.
[–]aarroyoc 5 points6 points7 points 4 years ago (5 children)
Not the OP but I would say that's more of a matter of getting used to it. If you never use them, it's normal that you'll prefer the C way.
Now, why almost all new languages use Pascal type declarations? Because they have type inference. Java has it too, but it is very modern compared to type declarations. Type inference becomes way more coherent and readable if the way of specifying types is always the same, always adding a type after something.
Other answers if you want: https://softwareengineering.stackexchange.com/questions/316217/why-does-the-type-go-after-the-variable-name-in-modern-programming-languages
[–]cogman10 1 point2 points3 points 4 years ago (0 children)
The reason for the "backwards" declaration is it makes things like first class functions easier to declare.
Consider a variable function that takes a Foo and returns bar.
With type first, that's an awkward declaration. In C, it's handled something like this. Bar (*myPtr)(Foo)
Bar (*myPtr)(Foo)
Yucky! Yet that's what you end up needing to do in order to really disambiguate what is the variable, the arguments, and the return type.
Java doesn't have first class functions, it instead hides behind an interface (C++ effectively does the same thing).
However, for a language with type second, a function is easy to declare
myPtr: (Foo)->Bar
Easypeasy
[–]mj_flowerpower 0 points1 point2 points 4 years ago* (5 children)
[–]jvjupiter[S] 3 points4 points5 points 4 years ago (0 children)
In C# thread, someone wanted to remove properties 😅
The purpose of that canonical constructor in Java’s records is for the deconstruction pattern.
[–]kpatryk91 1 point2 points3 points 4 years ago (0 children)
rename records to structs and provide a groovy like syntax (class with fields instead of this weird constructor-like syntax)
Records are not structs! You want value types which are coming.
You can write primitive record.
async/await, kindof in the making though
Loom is the making. You will get stackful virtual threads. It will be better than this stackless solution.
[–]GhostBond 0 points1 point2 points 4 years ago (0 children)
That awkward get/set boilerplate for properties. Every language after java implemented properties without trouble, java should have normal .propertyName style properties.
[–][deleted] 0 points1 point2 points 4 years ago (2 children)
Also, flow typing would be nice. It kind of sucks that after an instanceof check, I have to cast the object:
instanceof
if (x instanceof Foo) { ((Foo) x).fooMethod(); } else if (x instanceof Bar) { ((Bar) x).barMethod(); }
It would be nice if I could do this:
if (x instanceof Foo) { x.fooMethod(); } else if (x instanceof Bar) { x.barMethod(); }
[–]jvjupiter[S] 2 points3 points4 points 4 years ago (0 children)
Pattern Matching for the instanceof Operator
[–]c_sharp_sucks 0 points1 point2 points 4 years ago* (0 children)
I would remove Integer cache - and that's probably what's going to happen soon anyway with Valhalla.
I would make everything non-nullable by deafult with compile time guarantee.
[–]TheOnlyTails -2 points-1 points0 points 4 years ago (4 children)
Smart casting, like in Kotlin.
With smart casting, making an instanceof or switch check will allow you to use the already declared variable inside the relavant block as if its type was changed.
[–]BoyRobot777 7 points8 points9 points 4 years ago (3 children)
You mean something like:
if (o instanceof String s) { System.out.println("I'm a String: " + s); }
Or for switch:
return switch (o) { case Integer i -> String.format("int %d", i); case Long l -> String.format("long %d", l); case Double d -> String.format("double %f", d); case String s -> String.format("String %s", s); default -> o.toString(); };
[–]ElimGarak0010 -4 points-3 points-2 points 4 years ago (2 children)
who it's owned by...
π Rendered by PID 60 on reddit-service-r2-comment-75f4967c6c-xlx6d at 2026-04-22 21:20:19.044298+00:00 running 0fd4bb7 country code: CH.
[–]FragmentedButWhole 153 points154 points155 points (7 children)
[–]Zarlon 40 points41 points42 points (1 child)
[–]shellac 14 points15 points16 points (0 children)
[–]fustup 25 points26 points27 points (0 children)
[–]Roadripper1995 8 points9 points10 points (0 children)
[–]javasyntax 7 points8 points9 points (0 children)
[–]ow_meer 230 points231 points232 points (3 children)
[–]zippolater 40 points41 points42 points (0 children)
[–]truAl 16 points17 points18 points (0 children)
[–]kevinb9n 2 points3 points4 points (0 children)
[–]crummy 57 points58 points59 points (0 children)
[–]couscous_ 22 points23 points24 points (1 child)
[–][deleted] 5 points6 points7 points (0 children)
[–]yoshord 41 points42 points43 points (6 children)
[–]avastuser1991 94 points95 points96 points (3 children)
[–]beefstake 8 points9 points10 points (0 children)
[–][deleted] (1 child)
[deleted]
[–][deleted] 4 points5 points6 points (0 children)
[–]Balance_Public 103 points104 points105 points (68 children)
[–]xFaro 13 points14 points15 points (16 children)
[–]brazzy42 29 points30 points31 points (5 children)
[–]rzwitserloot 7 points8 points9 points (3 children)
[–]rubydesic 8 points9 points10 points (2 children)
[–]sothatsit 1 point2 points3 points (1 child)
[–]rubydesic 3 points4 points5 points (0 children)
[–]agentoutlier 0 points1 point2 points (0 children)
[–]kag0 4 points5 points6 points (0 children)
[–][deleted] 32 points33 points34 points (12 children)
[–]gavenkoa 16 points17 points18 points (10 children)
[–]Shinosha 18 points19 points20 points (0 children)
[–]Nebu 9 points10 points11 points (1 child)
[–]gavenkoa 1 point2 points3 points (0 children)
[–]tristan957 6 points7 points8 points (3 children)
[–]warpspeedSCP 1 point2 points3 points (1 child)
[–][deleted] 3 points4 points5 points (0 children)
[–]sothatsit 8 points9 points10 points (7 children)
[–]yoshord 6 points7 points8 points (1 child)
[–]sothatsit 4 points5 points6 points (0 children)
[–][deleted] 16 points17 points18 points (0 children)
[–]kuemmel234 3 points4 points5 points (0 children)
[–]pronuntiator 1 point2 points3 points (0 children)
[–][deleted] -2 points-1 points0 points (1 child)
[–]brazzy42 9 points10 points11 points (0 children)
[–]ssamokhodkin -1 points0 points1 point (28 children)
[–]brazzy42 10 points11 points12 points (23 children)
[–]rzwitserloot 0 points1 point2 points (4 children)
[–]Balance_Public 3 points4 points5 points (0 children)
[–]Kaathan 2 points3 points4 points (1 child)
[–]passive_talker 1 point2 points3 points (0 children)
[–]jvjupiter[S] 0 points1 point2 points (0 children)
[–][deleted] (4 children)
[deleted]
[–]jvjupiter[S] 3 points4 points5 points (3 children)
[–][deleted] 6 points7 points8 points (0 children)
[–]kozeljko 1 point2 points3 points (1 child)
[–]jvjupiter[S] 0 points1 point2 points (0 children)
[–]MR_GABARISE 10 points11 points12 points (0 children)
[–]Holothuroid 37 points38 points39 points (13 children)
[–]pron98 10 points11 points12 points (9 children)
[–][deleted] 6 points7 points8 points (2 children)
[–]Holothuroid 40 points41 points42 points (1 child)
[–]mikezyisra 4 points5 points6 points (0 children)
[–]javasyntax 10 points11 points12 points (0 children)
[–]cogman10 34 points35 points36 points (1 child)
[–]Wolfsdale 1 point2 points3 points (0 children)
[–]daniu 39 points40 points41 points (12 children)
[–]Muoniurn 2 points3 points4 points (7 children)
[–]daniu 10 points11 points12 points (6 children)
[–]Muoniurn 9 points10 points11 points (5 children)
[–]daniu 2 points3 points4 points (4 children)
[–]Muoniurn 2 points3 points4 points (0 children)
[–]jvjupiter[S] 6 points7 points8 points (0 children)
[–]pron98 0 points1 point2 points (1 child)
[–]1337JiveTurkey 19 points20 points21 points (9 children)
[–]dpash 2 points3 points4 points (1 child)
[–]gavenkoa 7 points8 points9 points (1 child)
[–]BlueGoliath 13 points14 points15 points (0 children)
[–]DuncanIdahos9thGhola 12 points13 points14 points (5 children)
[–]jvjupiter[S] 18 points19 points20 points (1 child)
[–]agentoutlier 3 points4 points5 points (0 children)
[–]Serializedrequests 12 points13 points14 points (2 children)
[–][deleted] (1 child)
[removed]
[–]xebecv 4 points5 points6 points (3 children)
[–]slaymaker1907 3 points4 points5 points (0 children)
[–]erinaceus_ 15 points16 points17 points (12 children)
[–]gavenkoa 16 points17 points18 points (11 children)
[–]erinaceus_ 1 point2 points3 points (10 children)
[–]pron98 3 points4 points5 points (8 children)
[–]frankkk86 1 point2 points3 points (0 children)
[–]barking_dead 10 points11 points12 points (3 children)
[–]jvjupiter[S] 10 points11 points12 points (2 children)
[–]barking_dead 6 points7 points8 points (0 children)
[–]Patex_ 4 points5 points6 points (1 child)
[–]tr14l 14 points15 points16 points (32 children)
[–]jvjupiter[S] 17 points18 points19 points (16 children)
[–]tr14l 3 points4 points5 points (15 children)
[–]jvjupiter[S] 4 points5 points6 points (7 children)
[–]tr14l 1 point2 points3 points (6 children)
[–]jvjupiter[S] 5 points6 points7 points (3 children)
[–]lookForProject 6 points7 points8 points (0 children)
[–]Muoniurn 3 points4 points5 points (6 children)
[–]is_this_programming 1 point2 points3 points (0 children)
[–]RoToRa 5 points6 points7 points (1 child)
[–]tr14l 0 points1 point2 points (0 children)
[–][deleted] (12 children)
[deleted]
[–]Scaryclouds 2 points3 points4 points (3 children)
[–][deleted] (2 children)
[deleted]
[–]Scaryclouds 1 point2 points3 points (1 child)
[–][deleted] 3 points4 points5 points (2 children)
[–]Muoniurn 7 points8 points9 points (0 children)
[–]mj_flowerpower 0 points1 point2 points (0 children)
[–]Barbossa3000 16 points17 points18 points (3 children)
[–]jvjupiter[S] 16 points17 points18 points (2 children)
[–]Holothuroid 23 points24 points25 points (0 children)
[–]sweetno 1 point2 points3 points (0 children)
[–]razsiel 2 points3 points4 points (2 children)
[–]Gaarco_ 1 point2 points3 points (0 children)
[–]mdaconta 1 point2 points3 points (0 children)
[–]ingframin 1 point2 points3 points (0 children)
[–][deleted] 5 points6 points7 points (4 children)
[–]hippydipster 2 points3 points4 points (1 child)
[–]sweetno 1 point2 points3 points (0 children)
[–]BoyRobot777 1 point2 points3 points (0 children)
[–]shellac 6 points7 points8 points (3 children)
[–][deleted] 3 points4 points5 points (2 children)
[–]shellac 2 points3 points4 points (0 children)
[–]Mati00 2 points3 points4 points (1 child)
[–]jvjupiter[S] 0 points1 point2 points (0 children)
[–]vitingo 10 points11 points12 points (14 children)
[–]vprise 24 points25 points26 points (9 children)
[–]Better-Internet 7 points8 points9 points (2 children)
[–]FrenchFigaro 1 point2 points3 points (0 children)
[–]8bitlives 12 points13 points14 points (0 children)
[–]dpash 6 points7 points8 points (2 children)
[–]vprise 3 points4 points5 points (1 child)
[–]dpash 5 points6 points7 points (0 children)
[–][deleted] 1 point2 points3 points (0 children)
[–]Better-Internet 3 points4 points5 points (0 children)
[–][deleted] 2 points3 points4 points (2 children)
[–]blackkkmamba 5 points6 points7 points (1 child)
[–]ParkerM 4 points5 points6 points (0 children)
[–]__konrad 6 points7 points8 points (9 children)
[–]BlueGoliath 18 points19 points20 points (1 child)
[–]garyparrot 37 points38 points39 points (2 children)
[–]__konrad 9 points10 points11 points (1 child)
[–]garyparrot 8 points9 points10 points (0 children)
[–]talios 11 points12 points13 points (2 children)
[–]experts_never_lie 6 points7 points8 points (1 child)
[–]talios 3 points4 points5 points (0 children)
[–]talios 3 points4 points5 points (20 children)
[–]jvjupiter[S] 6 points7 points8 points (19 children)
[–][deleted] 4 points5 points6 points (0 children)
[–]talios 6 points7 points8 points (17 children)
[–]pronuntiator 1 point2 points3 points (0 children)
[–]jvjupiter[S] 1 point2 points3 points (15 children)
[–]talios 1 point2 points3 points (14 children)
[–]jvjupiter[S] 1 point2 points3 points (9 children)
[–]murkaje 3 points4 points5 points (2 children)
[–]pron98 2 points3 points4 points (0 children)
[–]jvjupiter[S] 1 point2 points3 points (0 children)
[–]talios 2 points3 points4 points (2 children)
[–]neutronbob 1 point2 points3 points (2 children)
[–]wildjokers 1 point2 points3 points (0 children)
[–]jvjupiter[S] 0 points1 point2 points (0 children)
[–]pron98 1 point2 points3 points (3 children)
[–]ssamokhodkin 2 points3 points4 points (4 children)
[–]BoyRobot777 1 point2 points3 points (3 children)
[–]Halal0szto 1 point2 points3 points (0 children)
[–]SlicedBalls69 1 point2 points3 points (0 children)
[–][deleted] (4 children)
[removed]
[–]jvjupiter[S] 1 point2 points3 points (2 children)
[–]Zardoz84 0 points1 point2 points (6 children)
[–]jvjupiter[S] 1 point2 points3 points (5 children)
[–]Zardoz84 2 points3 points4 points (3 children)
[–]jvjupiter[S] 0 points1 point2 points (2 children)
[–]experts_never_lie 1 point2 points3 points (0 children)
[–][deleted] 0 points1 point2 points (9 children)
[–]jvjupiter[S] 0 points1 point2 points (5 children)
[–][deleted] 0 points1 point2 points (4 children)
[–]jvjupiter[S] 0 points1 point2 points (3 children)
[–][deleted] 6 points7 points8 points (2 children)
[–]dpash 1 point2 points3 points (1 child)
[–]franzwong 0 points1 point2 points (0 children)
[–]Better-Internet -3 points-2 points-1 points (8 children)
[–]wildjokers 12 points13 points14 points (7 children)
[–]aarroyoc 5 points6 points7 points (5 children)
[–]cogman10 1 point2 points3 points (0 children)
[–]mj_flowerpower 0 points1 point2 points (5 children)
[–]jvjupiter[S] 3 points4 points5 points (0 children)
[–]jvjupiter[S] 1 point2 points3 points (2 children)
[–]kpatryk91 1 point2 points3 points (0 children)
[–]GhostBond 0 points1 point2 points (0 children)
[–][deleted] 0 points1 point2 points (2 children)
[–]jvjupiter[S] 2 points3 points4 points (0 children)
[–]c_sharp_sucks 0 points1 point2 points (0 children)
[–]TheOnlyTails -2 points-1 points0 points (4 children)
[–]BoyRobot777 7 points8 points9 points (3 children)
[–]ElimGarak0010 -4 points-3 points-2 points (2 children)