• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Writing "good" java?

 
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Programming languages often have several legal ways to do something, and certain ways that experienced programmers tend to go.

I’ve heard it called “idiomatic”. The way native speakers speak. This is different from a style guide that might say how to name variables or how to indent.

Is there such a thing as “idiomatic java” and where can I learn more about it?
 
Rancher
Posts: 1093
29
Netbeans IDE Oracle MySQL Database Tomcat Server C++ Java
  • Likes 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You are talking, believe it or not, mostly style, but programmers that have been around for a while tend to get beaten in to the following category:

1 -- make it readable and maintainable
2 -- see #1

Now there are several books out there that talk about good code: I will leave that to you to find them. I have read literally 100's of books on programming in my career and it comes down to as I have already listed "make it readable and maintainable" anything other than that is just bad coding.
 
Marshal
Posts: 79151
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Welcome to the Ranch

Have you been taught the principles of object‑oriented programming? Each class should be responsible for itself, lots of small methods, make the code simple and straightforward, etc. Also about naming variables, etc.
 
Pito Salas
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes I've done lots of OO. Let me give you the context. I come from the Ruby community where people regularly exchange ideas about the 'best way' or the 'idiomatic way' to do something. It seems (because I've posted this in a couple of places) that this is not the way the Java community thinks about this.

Concrete example: It's legal to put a second, non-public, top level class in a file. Is there a conventional wisdom about when that's a good idea, if ever? And there are lots more questions like that. I want to write Java code that doesn't just compile and work but would be considered to be "good code" by an experienced Java programmer.
 
Campbell Ritchie
Marshal
Posts: 79151
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The Sun style guide is very old, but it does tell you how many classes to put in a file.
 
Saloon Keeper
Posts: 15484
363
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think to learn the idioms of a language, you just have to hang out in its communities a lot.

For instance, if you were to browse CodeRanch a bit, you'd find many discussions about how to make types immutable, about singletons, about having classes extend graphic components, about how to use the new functional programming API, about how to open and close a file correctly, etc.

When you're in doubt about your code, you can always post parts of it for people to review, and you'll eventually become comfortable with your own work.
 
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Pito Salas wrote:Yes I've done lots of OO. Let me give you the context. I come from the Ruby community where people regularly exchange ideas about the 'best way' or the 'idiomatic way' to do something. It seems (because I've posted this in a couple of places) that this is not the way the Java community thinks about this.


I'm not so sure about that. We have many threads that discuss precisely what the "best" way of doing something is - and of course, you'll have lots of different opinions about it.

A few of my mantras are:
1. Write dumb code.
2. WHAT is much more important than HOW.
3. Use Javadoc. Everywhere.
4. Good naming is the secret to good programming.
5. 'final' is your friend.
6. Tell, don't ask.
7. Keep lines short. When I'm using Eclipse, I set the line boundary at 75, which keeps most lines under 80 characters - which oddly enough, is the width of an old coding sheet.

Concrete example: It's legal to put a second, non-public, top level class in a file. Is there a conventional wisdom about when that's a good idea, if ever?


I can't say I've ever found a need. But I DO use non-public nested classes; and the rules for those are the same as for any other form of encapsulation - DON'T give away ANY information that is not absolutely essential. I also like public nested classes, and probably use them more than most.

I'm also a big fan of skeleton implementations - eg, AbstractList (←click). The Java tutorials refer to them as "abstract" implementations.

So there you go. A few things to be going on with.

HIH

Winston
 
Marshal
Posts: 8856
637
Mac OS X VI Editor BSD Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Apart from the fact, that mostly of the staff here programming over decade, two or even three or so, others are simply enthusiasts, so by posting your doubts about your code here, you could benefit from getting suggestions which are proven by time or just because of simply everyone discussed that code hundreds of time here and found most likely most efficient solution of it.

I, as a small fish, who still learning and trying to catch up with, got copy of Joshua Bloch "Effective Java" book, which teaches you those best practices, describes most common scenarios, possible pitfalls and how to deal with them if when you face one.
Another book I could recommend is "Clean Code" by Robert C. Martin, it could give you a better understand about the good variables, methods naming and what secrets it brings to your code (what Winston mentioned) and in general what clean and readable code means, which most likely will be also easy maintainable.

Also you could find Wiki forum here, where you could find lots of written FAQ's and tutorials.

The sum of all those things, could give you the output of what you mentioned in your initial post.

And a warm welcome to the Ranch
 
Pito Salas
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks everyone for the constructive suggestions, I appreciate it!
 
Campbell Ritchie
Marshal
Posts: 79151
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Liutauras Vilda wrote:. . . Joshua Bloch "Effective Java" book, . . . "Clean Code" by Robert C. Martin, . . .

Both good books. It would be good if Bloch wrote a new edition of his book, which is getting on for 8 years old.
 
Sheriff
Posts: 22781
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I don't think it's really necessary. I re-read the book last year, and all of it was still accurate; the only thing that has become invalid was Josh saying that interfaces couldn't contain non-abstract methods. Although he may want to add some topics on lambdas, I still haven't read a good book about how to properly use them.
 
Marshal
Posts: 28177
95
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
As an example of how Java programmers usually write something which can be done in several ways:



This iterates through indexes from 0 to max-1, usually over an array. I'm sure our old-time C programmers can come up with half a dozen equivalent formulations but this is the way it SHOULD be written in Java. Unless you can use the enhanced for-loop, in which case you SHOULD do that instead. However you're going to see that indexing style for a long time regardless of how obsolete it is, because there's a widespread programming methodology out there where you google for scraps of code which look like they do what you want and insert those scraps into your code base.

Likewise the code for processing lines from a BufferedReader:



That isn't the obvious way a beginner would write it, but it's the way it SHOULD be written in Java. Although that too has been superseded in Java 8 by



 
Pito Salas
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
@paul: Really good stuff. You understand exactly what I was asking about! The question I posed about putting a non-embedded non-public class in the same file as a public one. What have you seen/believe?
 
Pito Salas
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Actually on your reader example, why is it necessary (or is it) to declare String line outside the loop?
 
Paul Clapham
Marshal
Posts: 28177
95
Eclipse IDE Firefox Browser MySQL Database
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Pito Salas wrote:The question I posed about putting a non-embedded non-public class in the same file as a public one. What have you seen/believe?



I've seen a lot of open-source Java code and I've seen that done exactly once. I spent a lot of time searching for the source code of the secondary class before I figured out what was going on. So I would say that definitely is NOT a Java idiom.
 
Paul Clapham
Marshal
Posts: 28177
95
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Pito Salas wrote:Actually on your reader example, why is it necessary (or is it) to declare String line outside the loop?



I don't believe it is necessary. And I wouldn't make a fuss if you declared it inside the loop either.
 
Paul Clapham
Marshal
Posts: 28177
95
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Declaration of arrays is another example:

 
Ranch Hand
Posts: 234
12
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Paul Clapham wrote:I've seen a lot of open-source Java code and I've seen that done exactly once. I spent a lot of time searching for the source code of the secondary class before I figured out what was going on. So I would say that definitely is NOT a Java idiom.


I don't think that putting a non-public top-level class in the same file as a public top-level class is any different than putting a non-public nested top-level class in the same class as an enclosing public top-level class, for example the non-public nested javax.swing.AbstractButton.ButtonChangeListener class is used only by the public javax.swing.AbstractButton class. This is done simply for convenience if a class is used only by another class.

The public shouldn't care about locating the source code for the non-public class. Only insiders know the location of the non-public class.

For example, if I am a programmer at coderanch.com and I'm working on classes in the com.coderanch package and a non-public com.coderanch.RanchButtonChangeListener class is used only by a public com.coderanch.RanchAbstractButton class, then, for convenience, I might choose to put the com.coderanch.RanchButtonChangeListener class in the same file as the com.coderanch.RanchAbstractButton class. This is done simply for convenience amongst programmers at coderanch.com. Only programmers at coderanch.com are aware of and need to know the location of the com.coderanch.RanchButtonChangeListener class.
 
Stephan van Hulst
Saloon Keeper
Posts: 15484
363
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Pito Salas wrote: The question I posed about putting a non-embedded non-public class in the same file as a public one. What have you seen/believe?


I try to avoid it, but in some cases I enjoy nesting classes because it accurately displays the relationship between types. One of my favorite examples:

Other classes would then refer to these types as ChessPiece.Color and ChessPiece.Type, which differentiates them from say, Rainbow.Color. It also gives related classes (such as ChessBoard) the opportunity to do a static import, so instead of having to write ChessPieceColor all over the place, you can just use Color.
 
Sheriff
Posts: 17644
300
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Paul Clapham wrote:However you're going to see that indexing style for a long time regardless of how obsolete it is, because there's a widespread programming methodology out there where you google for scraps of code which look like they do what you want and insert those scraps into your code base.


I don't agree with the characterization of the indexed for-loop as "obsolete". There are times when you legitimate can't use the for-each construct because you actually do need index variables, like when you're implementing a sorting algorithm like selection sort or bubble sort or when you are working with a data structure that uses some kind of coordinate system to access its elements.

As to the OP's question about idiomatic Java, there are many idioms for Java but as Paul hinted, there's also a lot of copy-pasting noise. Being able to discern good from bad comes with experience, I suppose, but I pretty much subscribe to the same guidelines that Les Morgan gave in his reply.

As for style vs idiom, I think there's a fine line that separates the two. I recently had a short discussion where another developer argued that the following was more readable to him

I argued that this was redundant and the idiom is to just return the Boolean expression result in one line. He eventually acquiesced, albeit reluctantly, while still saying that he thought it was just a matter of style.

BTW, since someone mentioned two of my favorite books, I'll also mention another one that's at the top of my stack of references-within-easy-reach: "4 Rules of Simple Design" by Corey Haines. This is by far the best book I've ever read that focuses on clean, simple, testable code and designs.
 
Junilu Lacar
Sheriff
Posts: 17644
300
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Paul Clapham wrote:

Pito Salas wrote:The question I posed about putting a non-embedded non-public class in the same file as a public one. What have you seen/believe?


I've seen a lot of open-source Java code and I've seen that done exactly once. I spent a lot of time searching for the source code of the secondary class before I figured out what was going on. So I would say that definitely is NOT a Java idiom.



At the risk of reading too much into Paul's response, I would say that while it may not be a very common thing to see thus making it NOT an idiom, I don't necessarily see it as a poor practice, especially if your intent is to make the secondary class have very limited scope. I don't know why you'd spend a lot of time searching for the source code of the secondary class unless you're just browsing through the source on the web or in a plain text editor. Most IDEs can find it for you with a couple of clicks of the mouse.

Say you were writing this secondary class and for some reason didn't want to make it an embedded private class. However, the public class is the only thing that uses the secondary class at the moment and you're still not ready to make the secondary class a public one. Keeping the secondary class in the same compilation unit as the public one that uses it is still, IMO, a good hedge to give other programmers a hint of the intent to limit its scope. Of course, a well placed comment to explain your motivation will be really helpful. Communicating your motivations in cases like this is key to avoiding confusion.
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Paul Clapham wrote:

Pito Salas wrote:Actually on your reader example, why is it necessary (or is it) to declare String line outside the loop?

I don't believe it is necessary. And I wouldn't make a fuss if you declared it inside the loop either.


For example:
  for (String line = br.readLine(); line != null; line = br.readLine()) { ...
which is actually more "Dijkstra-like" too.

It's surprising how seldom you see it though.

Winston
 
Stephan van Hulst
Saloon Keeper
Posts: 15484
363
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I used to do that, but I stopped doing it because it confuses so many people. Instead, before Java 8 I went with the following, even if that means that I have a variable declared out-of-scope:
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Paul Clapham wrote:That isn't the obvious way a beginner would write it, but it's the way it SHOULD be written in Java. Although that too has been superseded in Java 8 by


However, I'd still argue that isn't "idiomatic".

I find it odd, for example, that, even with Streams, in order to read a file the way most of us would like to, we're forced to write:when BaseStream already has a perfectly good iterator() method.

Why the hell couldn't they just have had it implement Iterable<T>?

I have no problem with introducing functional paradigms into the language, but don't force it on us straight out of the starting gate.
I also wonder how many custom stream wrappers will be written as a result of that little "omission"?

Winston
 
Rob Spoor
Sheriff
Posts: 22781
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
That can be fixed quite easily, but it does involve a cast:

The main question is, though: why not do something with line as a consumer?
 
Paul Clapham
Marshal
Posts: 28177
95
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Junilu Lacar wrote:I don't know why you'd spend a lot of time searching for the source code of the secondary class unless you're just browsing through the source on the web or in a plain text editor. Most IDEs can find it for you with a couple of clicks of the mouse.



I spent a lot of time searching for the secondary class because I hadn't ever seen anybody hide it in with the primary class before. And this was after several years of being a Java programmer. So it didn't even occur to me that was a possibility. It also didn't occur to me to use the IDE to search for the secondary class because I didn't know there was that option. Sure, I knew about the search function to find places where a class is used, but it never occurred to me that searching for the declaration of a class would be useful. To this day I have still never had to search for the declaration of a class in a project -- the fully qualified name of the class tells you where it should be.

Of course, a well placed comment to explain your motivation will be really helpful.



Yes, a well-placed comment would have been helpful. You should always use a comment when using obscure and little-known features.
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Rob Spoor wrote:The main question is, though: why not do something with line as a consumer?


Because, in the words of the question (and at least as I understand the term), it's not "idiomatic".

It may become so a few years down the road, when we have a new generation brought up with all these new "functional" goodies, but it certainly isn't now; so why should I be forced to write a Consumer to probably do exactly what I was going to do in my for block? Let alone use a very "iffy" form of casting.

We've had Streams and functional interfaces and lambdas and Consumers for a little less than 2 years now and, while I really like them for some things, I certainly don't think they're applicable to all, and I trust Java programmers to find a "happy medium" of procedural and functional logic if they're given the tools.

It also strikes me as unlikely that this was actually an omission, because I simply can't believe it didn't occur to the author of the iterator() method that "Hey, that means a Stream can be an Iterable". I think it far more likely that someone (probably a committee) decided that we all need to embrace "functionality" straight away, and that it would send the wrong message for any of this new stuff to have links back to the "old ways".

And if I'm right, I think it's a mistake.

Winston
 
Paul Clapham
Marshal
Posts: 28177
95
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Winston Gutkowski wrote:so why should I be forced to write a Consumer to probably do exactly what I was going to do in my for block? Let alone use a very "iffy" form of casting.



That Consumer is what Rob and I both posted:



I don't think it's that onerous to put "line ->" before your code to make it a Consumer. And there isn't any casting in this code, although perhaps you were referring to the casting required for your functional/procedural hybrid version?
reply
    Bookmark Topic Watch Topic
  • New Topic