20 ms·
The I/O example is moot since Java 11 where Java got https://docs.oracle.com/en/java/javase/13/docs/api/java.base/java/nio/file/Files.html#readString(java.nio.f
by JanecekPetr 7y ago
The I/O example is moot since Java 11 where Java got https://docs.oracle.com/en/java/javase/13/docs/api/java.base/java/nio/file/Files.html#readString(java.nio.file.Path) https://docs.oracle.com/en/java/javase/13/docs/api/java.base..., so we can do `Files.readString(Paths.get(doc.txt))`.
Java 14 is getting an experimental preview of Records (https://openjdk.java.net/jeps/359 https://openjdk.java.net/jeps/359) which takes care of much (but not all) of ceremony around "data classes".
And Java 13 got a preview of text blocks, https://openjdk.java.net/jeps/355 https://openjdk.java.net/jeps/355.
Things are coming. That said, I hardly believe those minor syntax improvements are what is so "good" about Kotlin. It has some better defaults (non-null by default, final classes by default), and is a more modern language. Java will stay with us for many years to come, though.
- driver733 7y agoYou are right, but you still have to catch the checked IOException.
- deepsun 7y agoI actually like it. I also create my own exceptions for rare (exceptional) cases, just not to forget to handle them. But some Java SDK exceptions drive me crazy. For example `URL.parse("http://example.com")` http://example.com")` over hard-coded strings that I know 100% won't throw exceptions, but I still to catch 3 of them.
- vips7L 7y ago`URI.create("https://example.com")` https://example.com")`
- twic 7y agoThat's why URI has a factory method that you're only supposed to use for known strings (although of course this can't be checked): https://docs.oracle.com/javase/7/docs/api/java/net/URI.html#create(java.lang.String) https://docs.oracle.com/javase/7/docs/api/java/net/URI.html#... After URI appeared in 1.4, the only reason to use URL was to create a URLConnection from a URI. Since openConnection() throws IOException, it's not a big deal that toURL() throws a MalformedURLException - just catch it along with all the other IOExceptions. Since 11, there's no reason to use URL at all, because you can use HttpClient to actually do HTTP.
- meddlepal 7y agoOk I'm a veteran Java developer that understands exactly what you're saying but try explaining that to people unfamiliar with Java or junior engineers and watch their brains glaze over. The JDK is filled with a ton of dumb "once upon a time we thought this was okay..." things that don't properly encode the correct modern idiom
- xenomachina 7y agoFor a long time I've wanted a sort of "local deprecation" tool where we could have a list of things in the JDK that shouldn't be used, and any direct reference to them would cause our build to fail.
- erik_seaberg 7y agohttps://errorprone.info/ https://errorprone.info/ can be configured to look at the AST and warn or reject a lot of specific problems.
- cesarb 7y agoWe use https://github.com/policeman-tools/forbidden-apis https://github.com/policeman-tools/forbidden-apis for that.
- twic 7y agoYes, it absolutely is! But then so are all other languages of its vintage. Part of learning a programming language is learning that. Newer languages definitely have an advantage here, in that they haven't been around long enough for people to have figured out which bits of them are dumb.
- ivolimmen 7y agoIt's worse. In 1.4 they added URI because URL is very flawed. You should never use URL. The equals method actually does a DNS resolve and compares the ip addresses. This means that comparing two URL's on the same server will always return true when compared. A lot of URL's you compare will give you true as there are a lot of sites run on the same machine with the same ip address.
- twic 7y agoAbsolutely wild how people are all in favour of Either/Result, but still look down on checked exceptions.
- driver733 7y agoYou might find this article interesting. https://www.pragmaticobjects.com/chapters/001_checked_exceptions.html https://www.pragmaticobjects.com/chapters/001_checked_except...
- twic 7y agoI've been reading articles like this for twenty years now, and i've never found one anything other than idiotic.
- Fellshard 7y agoI love both, but Java's implementation of checked exceptions cause harder and harder problems, especially when combined with tools such as lambdas, since there's no way to generically compose or handle checked exceptions inside them.
- hota_mazi 7y agoJava's implementation of checked exceptions looks pretty minimal and sound to me. How would you implement them?
- Fellshard 7y agoIt's certainly fair to say I have no alternative recommendation. I enjoyed using them prior to Java 8, and they gave the guarantees I was looking for. They have just had a much harder time integrating with newer features than could be hoped for. I'm not sure how much of that is intrinsic to checked exceptions, and how much is intrinsic to Java's implementation. One example of this: there is no way to encode the type of a checked exception in a generic. I would like to be able to express something like the following: interface ExceptionHandler<E extends Exception, S, T> { T wrap( Function<S, T, throwing E> fn, Function<E, T> exceptionMapper ); } But there is no way to express that 'throwing E' part. The type of a checked exception is firmly embedded in the interface. So I can't supply, say, an IO method as a Function<S, T> parameter, since the IOException causes a mismatch, and I'd have to write a handler specifically for methods that throw IOException, another for those that throw TimeoutException, a third for those that throw IOException AND TimeoutException, etc; a fairly fruitless goal without automatic code generation.
- bArray 7y ago> You are right, but you still have to catch the checked > IOException. Rather than which alternative? There are tonnes of IO errors that can occur and are captured in Java that you may not ever even consider. IO is exceptionally tough and programmers should be aware that there could be 1 of a possible million reasons for failure, even if they don't care exactly why. It's not a massive ask either: try{ /* Perform some IO that 99.999999% of the time */ }catch(Exception e){ /* Something went wrong and we don't know the state of the disk */ } Personally I believe applications should have their own wrapper around IO and handle it accordingly. I.e. not caring, re-trying, show-stopper, etc, etc. A lot of code I've written will have the following if I really don't care if it works or not: try{ /* IO code */ }catch(Exception e){ /* Do nothing */ // <-- Let others know that this was on purpose }
- nostrademons 7y agoFor a lot of scripts you want the program to crash with a stack trace if you get an IOException, which is the default behavior if it's uncaught. The user is the developer, and if there's an error the developer fixes it by munging something on their filesystem. Java was designed for "production" software, which in the late 90s and early 00s meant software that ran for long periods of time as a server, servicing thousands of mission-critical customers. Crashing was not acceptable behavior for that. But now a lot of production software often requires a lot of ancillary one-off tasks that are just done by the developers - testing, data-munging, exploratory code, migrations, demos, etc. That's a very different environment from where you code to spec, the spec never changes, and once the software is done it's supposed to run for years without crashing.
- erik_seaberg 7y agoEarly Java was designed for set-top boxes and then web browsers. Large-scale servers came later; in fact a lot of libraries still don't support the async futures that were officially added five years ago.
- paulddraper 7y ago99% of the time I want to do the same thing for IOException as I would for NoSuchElementException or a DOMException. That said, even if typed checked exception handling is important...it quickly becomes untenable. Thing thing = create(); try { ... } finally { cleanup(thing); } You might try to abstract this withThing(thing -> ...) But what if "..." potentially throws IOException? What if it potentially throws IOException or AWTException? You have to give up all your exception type safety to make an abstraction like withThing. It's just not composable.
- madiathomas 7y agoChecked Exceptions are the main reason I switched to C#.NET. I hated checked exception. I know the designers wanted to save us from ourselves but they ended up making the language verbose.
- guelo 7y agoI wonder if Java's speeding up of new language features over the past several years, after many years of a stagnant feature set, is a direct result of pressure from the likes of kotlin.
- hinkley 7y agoWho has it now is a good question, but so too is 'who had it first'. And if you also consider the upgrade treadmill, and where the average Java developer is relative to say ten years ago, it may turn out that at any given point in time, the Kotlin version you'd be able to deploy may have a number of features the most recent Java version you could deploy does not have. (to say nothing of companies where 'the version' is decided by committee or fiat and thus having a more obscure language sometimes gets you less scrutiny).
- hyperpallium 7y agoAsk "how does Oracle benefit?"
- _akei 7y agoIt is mostly C# that is keeping Java on their toes. Java competes with C# than any other language in this world. In the enterprise space, it is either Java or C#. If you check most of their improvements, they were done ion C# first, then they follow.
- guelo 7y agokotlin copied a lot from C# first.
- madiathomas 7y agoNow that is a good strategy. Copy directly from a language that is moving at a very fast pace and competing directly with the language you want to replace.
- pjmlp 7y ago