This week's giveaway is in the Spring forum.
We're giving away four copies of liveProject: Protecting User Data with Spring Security and OAuth2 and have Laurentiu Spilca on-line!
See this thread for details.
Win a copy of liveProject: Protecting User Data with Spring Security and OAuth2 this week in the Spring forum!
  • 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
  • Paul Clapham
  • Ron McLeod
  • paul wheaton
  • Devaka Cooray
Sheriffs:
  • Jeanne Boyarsky
  • Tim Cooke
  • Liutauras Vilda
Saloon Keepers:
  • Tim Moores
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
  • Piet Souris
Bartenders:
  • salvin francis
  • Mikalai Zaikin
  • Himai Minh

Storing scanner in interface

 
Ranch Hand
Posts: 99
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Just a thought I had, Is it good practice to do this



putting the scanner object in an interface and then allowing any class that requires to take input to implement it?
 
Ranch Hand
Posts: 72
3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
No, it's a bad idea for several reasons:

1) according to java conventions Interfaces are not marked by an captial I - that's some slang often reused by folks comming over from other languages
2) Scanner has internal buffers: so accessing one instance in "random" order can cause issues due to data already consumed by some buffer that are actually required at sone other point - don't even try to use multiple Threads - it's a catastrophe waiting to unleash its nightmares
3) anything in an interface is public by definition - exactly the opposite of that any scope should be as narrow as possible
 
Sheriff
Posts: 16140
269
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I concur, it's a bad idea. In fact, I'll go one step further and say it's a horrific idea. Remember, an interface is primarily a definition of behavior. Don't make it a bucket for some infrastructure utility just because it might make some things easier to do. Coupling an interface to an implementation like that is bad, bad, bad. Don't do it, no matter how useful you might think it would be.
 
Kevin O'Sullivan
Ranch Hand
Posts: 99
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
ok thanks for the replies, was just a thought I had.
 
Matthew Bendford
Ranch Hand
Posts: 72
3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Junilu Lacar wrote:I concur, it's a bad idea. In fact, I'll go one step further and say it's a horrific idea. Remember, an interface is primarily a definition of behavior. Don't make it a bucket for some infrastructure utility just because it might make some things easier to do. Coupling an interface to an implementation like that is bad, bad, bad. Don't do it, no matter how useful you might think it would be.


As someone who would consider himself as "addicted to modularity by interfaces" (I really do like that stuff) I highly appreciate that one line sum it all up:
"as a class is a blueprint for an object - so an interface could be seen as a blueprint to classes"
Remember: A class somewhat describes what an instance of it, an object, should perform. If you go one step further one might say: An interface describes what functionality a class might offer. Ooh, I really like that anology (anyone: If this is wrong - please get me back down to earth.).

An example ai just came up with as I write it: A JDBC driver is called just that: Driver - it's an interface describing what functionalities a jdbc should offer to users of its implementation.
Same goes for one of the most common used typed of collection in Java: a List. It doesn't matter if it's an ArrayList or a DoubleLinkedList or some other specific implementation of some sort of List - all that matters is that it somehow guarantees the order of inserted entries, traversing thru/iterating over them - and random access in at least on direction. How a specific List implementation actually implements these keyfeatures is up to the implementation itself - as you only use the general List interface.

Same goes here: There's only exactly one instance of System.in - so try to access it with multiple caching instances of Scanner is no option. If you really rely on whatever Scanner offers you, you only should use one static semaphore instance within the whole VM instance. Be aware that neither System.in nor Scanner is Thread-safe - so you have to provide your own synchronization if you try to access either of them by several concurrent Threads.
For simple stuff all put into main() that's might not an issue - but as soon as you transition to GUIs and its maybe multiple Threads it's just a big nightmare waiting to unwrap itself. Thank god Java devs at least cut it down to one single self-synchronized gui edt.

So, usin Scanner: no issue if you kbow how to use it properly. Goin anywhere advanced try to read System.in? I'll already prepared "teh couch" for you.
 
Kevin O'Sullivan
Ranch Hand
Posts: 99
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Would a better option be just making the scanner instance static in your main class? and then you could use it across multiple classes.
 
Junilu Lacar
Sheriff
Posts: 16140
269
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Kevin O'Sullivan wrote:Would a better option be just making the scanner instance static in your main class? and then you could use it across multiple classes.

If you do a search, there are a few moderators who have their own utility classes for console keyboard input. This is probably the one time I wouldn't cringe at the thought of a singleton. Putting a static instance in your main class is still a bit of a misplaced responsibility. However, if the program is small enough and won't really be maintained long term, then it's not so bad. You have to strike a balance between simplicity and strict adherence to design principles.
 
Marshal
Posts: 72603
317
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Agreee that putting a field in an interface like that is a bad idea, because it allows different code access to the Scanner, and also loses you the reliability you can get from a well‑designed utility class. I would also argue that a method using a Scanner is a function: you give ti input and you get output. If you give it the same input again, you will get the same output. And nothing else happens in between. So it is a good idea to make such methods static (You woun't hear me recommending anything static often), which fits exactly with the concept of a utility class.
No, you can't do that with static interface methods; they are not inherited by implementing classes, and you also should keep the Scanner instance private.
I would also suggest that the time spent writing a utility class will repay itself because you won't have to worry about keyboard input again. All you will have to do is writeAnd you can be confident that it will work and that is one thing less to worry you You only need ”strict adherence to design principles” once. Then you can take it for granted that class will work correctly.
 
Matthew Bendford
Ranch Hand
Posts: 72
3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I agree with Campbell here: Although I myself not really like Scanner (mostly because I never put the required time into learning how to correctly use it) I see why it exists as part of the SE-api and that for a couple of use cases it might be not that bad of an idea. But, as I mentioned: One has to know how to correct implement its usage. This comes less from own experience but rather from the about countless numbers of threads that keeps appearing here from new devs new to Java not correctly understanding how to use Scanner.

System.in is a public static - so it's the very same instance all over within the same vm. And although it may makes it easy to access from pretty much anywhere within your code do so in a way that allow maybe more than one Thread concurrently to read the data you expect and to deal with user input errors there're several members of this forum already spent years or even decades on. So, although your question may not new to them - at least to my knowledge its answer currently remains: Don't do it. If you ask "Why?" you don't know enough about it. Keep learning until you can answer this question yourself - then you maybe ready to it the right way.

I don't mean to be rude - but, at least in my eyes, Scanner itself is. And for me it belongs to a group of classes I do understand why back in the 80s and 90s some devs ought them to be a good addition - but they proven themselfs as beginner pitfalls. I would even go that far as to claim: maybe remove, or at least change, these classes - no matter if it breaks backwards compatibility. Why? Cause starting with Java 9 a massive change started already breaking compatibility - and as most of code rely on current implementation isn't either mained or should be rewritten anyway.
 
Campbell Ritchie
Marshal
Posts: 72603
317
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Matthew Bendford wrote:. . . new devs new to Java not correctly understanding how to use Scanner . . . .

There is a worse problem than new people not understanding Scanner. I think lots of people, even experienced people, don't understand it, and (as Winston Gutkowski pointed out ages ago) I haven't seen many good tutorials about it, and books are often not clear about its vagaries. People find out it has vagaries, trip over them, and then dismiss the class as useless.
 
Campbell Ritchie
Marshal
Posts: 72603
317
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Another problem with having a Scanner instance public: Scanner is a mutable type, so it is possible for one block of code to change its state (e.g. its delimiter) and that will produce bugs for other code which relies on a different delimiter.
 
You showed up just in time for the waffles! And this tiny ad:
Building a Better World in your Backyard by Paul Wheaton and Shawn Klassen-Koop
https://coderanch.com/wiki/718759/books/Building-World-Backyard-Paul-Wheaton
reply
    Bookmark Topic Watch Topic
  • New Topic