4 ms·
Java is verbose. Tooling is great, however. For exceptions, there are two types. Checked exceptions and runtime exceptions. * Checked exceptions need to be
by AYBABTME 13y ago
Java is verbose. Tooling is great, however.
For exceptions, there are two types. Checked exceptions and runtime exceptions.
* Checked exceptions need to be explicitly handled in your code, or it doesn't compile.
* Runtime exceptions can just happen, you don't need to check them. I personally don't really like the runtime exceptions because they can hide in thousands of place and throw when you don't expect it. However, you don't need to check them so it makes for less verbose code... but it's like putting your head in the sand.
To reduce verbosity of exception handling, I find a pseudo-solution is to just propagate the exception up the stack and deal with it later. It depends for what exception, but for instance, a MalformedUrlException for which you KNOW the Url is fine, can be checked much higher in the call stack. You will save yourself the local verbosity, which hides meaning, and really if the Url is malformed, you might not want the app to keep running; if it's hard-coded you should expect it to be right. It's in the same spirit of Go's `regexp.MustCompile(string)` that makes a compile error if the hardcoded string you give it is not a valid regex.
That being said, Java is a daily pain, but the extensive tooling makes it usable.
- StavrosK 13y agoThanks for clarifying checked vs unchecked. Your comment makes perfect sense, and is what I expected. The thing is that I really don't like handling an exception higher than where it makes semantic sense (which is the actual call, in this case), so propagating higher is even less clean, for this specific example. I guess the problem here is the checked exception, but I can see the rationale, if it's impossible to optionally handle an unchecked exception.
- AYBABTME 13y agoWhat you could do is initialize the Url in a static block or in a `{{ }}` block and handle the exception there. You would still have the exception handling, but not in your logic, and the static block would ensure that if the Url is indeed malformed, the exception will throw as soon as the class is loaded in memory, instead of only when the Url is instantiated during in logic. So somewhere up in your class, you'd write: private final static URL someUrl; static { try { someUrl = new URL("http://something.com/"); } catch(SomeException e) { crashAndLogSomehow(e); } } You would thus know right when you load your app, before distributing it, whether an exception can happen. In your code, you wouldn't have the try/catch block hiding the real meaning.
- StavrosK 13y agoThanks, that's a better solution. I still dislike having to handle something that'll never happen, but this is probably the best one can do in this case.
- sfjailbird 13y agoPutting it in a static block is bad advice, there are many other places you could put initialization. What happens if a static block throws an exception is that the class will not be loaded, and every other time the code refers to the class it will get a ClassDefNotFoundException, which can lead to a 'fun' time tracing the actual issue. Hence why static blocks are not used very much (though it can be convenient).
- AYBABTME 13y agoThe idea is that if an exception has to be thrown, it will throw as early as possible, making it pretty obvious during development that there's a bug - whenever you try to run your app it will exit with an error about the MalformedUrl. Notice I said he/she should catch the exception in the static block and log it, pretty hard to have an issue tracking where the error comes from. You can't check at compile time that the Url is valid, but if as soon as you load the program, it crashes with this exception, it will be hard to ignore and the mistake won't be hidden. Since you catch the exception that's thrown a static time, there's no ClassDefNotFoundException. See examples of this concept in Go: http://golang.org/pkg/regexp/#MustCompile http://golang.org/pkg/regexp/#MustCompile http://golang.org/pkg/text/template/#Must http://golang.org/pkg/text/template/#Must The better solution would be to have a compile time error, but I don't think Java can do that.
- nahname 13y agoChecked exceptions. When your code is so instable, you make failure part of the API.
- famousactress 13y agoYeah, this is the argument I got tired of and why I jumped ship out of developing in Java for over a decade: "Java is pretty painful, but don't worry.. the tools are so good you don't have to write much code."
- ChikkaChiChi 13y agoThis blows my mind and this may be the reason I have so many problems dealing with frameworks of any kind. If I am writing live code, I...want to write code. I don't want something to do it for me. If its in a language I am comfortable with I can generally write it more effectively than a tool in a toolbox and know how to fix it when it breaks. Maybe I am just a control freak.
- famousactress 13y agoNo, you're normal. Couple things though: The knowing how to fix it when it breaks isn't a real problem in my experience with Java... the stuff that tools tend to generate for you is so boilerplate there's not much mystery there, so I never felt abstracted from the meat of the programs, really. The Java language, while I was using it, was very slow to change or evolve. Tools, on the other hand, didn't suffer from the bike-shedding and lack of leadership, so they evolved quickly to solve the pragmatic problems they could solve. When I decided to look around and choose a language to re-invest myself in I looked very closely at leadership.. Who the BDFL was (and whether one existed), how the language was evolving, and what the values of the community were. That meant more to me than syntax, though of course they're related. Sort of like "watch the player, not the ball" advice you get in soccer.
- kivikakk 13y agoregexp.MustCompile doesn't result in a compile error; it panics at runtime. The purpose is to simplify compiling regexps at the global level, and the assumption is it's a hard-coded regexp that can't be wrong.