?
Solved

System.in.read()

Posted on 2002-04-01
12
Medium Priority
?
386 Views
Last Modified: 2010-03-31
System.in returns and object of InputStream which is an abstract class and read() is an abstract method of this class. Then how does this work, since we need to implement this read in some subclass. How does this work?

0
Comment
Question by:motorway
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
  • 2
  • +3
12 Comments
 

Expert Comment

by:rashidkamranbs
ID: 6911040
Well well .. ya missed something very imporatnt.. let me tell ya how this happen the magic in OOP.. See.. when we design a class hierarchy.. what we do we place general behaviour in the top level calsses most of the time interfaces or abstract calsses the purpose is to create a common interface for all the classes belongs to or we place rite inthe bottom with concrete implementation..

Now what happen in this casee.. the Object assigns to InputStream .. which is System.in is actually an object of a class that completely implements the read method.. but cuz it extends the InputStream it is an input stream.. n can be assigned to the reference of type InputStream..

a possible impl could be..

InputStream in=new InputStream(){
  int read(){
    //do read here
  }  
};

What i want to show ya is the thing that Abstract Classes and intefaces just make contracts and concrete classes have to full fill the contract by providing implementation.. what about Name.. doesn't matter as i used Anonymous..  n yes.. late binding .. or what we call overriding.. is the key :-) hope i m clear.. sorry for being too long
0
 

Expert Comment

by:0xDEADBEEF
ID: 6912390
That depends on what you want to do.
Usually one of the classes derived from InputStream that come with the JDK work wuite well. Browse
http://java.sun.com/j2se/1.4/docs/api/java/io/InputStream.html
for more information on them. If these don't work for you, you'll have to write your own class. In case you want to use this  class on more than one occasion, you want to name it, like:

class myInputStream extends InputStream {
  //override methods here
}

In case you use it only once, you may want use an anonymous class, like rashidkamranbs mentioned. This looks like

BufferedInputStream myStream = new BufferedInputStream(new InputStream(){
     //TODO: Stuff
     private Random rnd();

     public int read(){
       return rnd.nextInt();
     }
  });

Hope this helps.
0
 

Expert Comment

by:0xDEADBEEF
ID: 6912392
Err... of course Random is instanciated like  

private Random rnd = new Random();

Too much C++ stuff lately...
0
Get 15 Days FREE Full-Featured Trial

Benefit from a mission critical IT monitoring with Monitis Premium or get it FREE for your entry level monitoring needs.
-Over 200,000 users
-More than 300,000 websites monitored
-Used in 197 countries
-Recommended by 98% of users

 

Author Comment

by:motorway
ID: 6912629
Thanx rashidkamranbsm, but i have one query.
There are many subclasses derived from inputstream implementing read() method. How does the interpreter come to know which version of read() to call.
0
 

Expert Comment

by:rashidkamranbs
ID: 6912641
Well this is something we call Late Binding.. (by the way in java all the function bindings are late)

At compile time compiler just verifies if the method exist or not.. and at run time the actual method is called..

Lemme give you an example

suppose you write a class

class MyInputStream extends InputStream{
   public void read(){
     //my read impl
   }
}

now suppose you write a line of code like
InputStream in=new MyInputStream();
in.read();

The compiler checks if read() exisit int inputstream or not cuz reference type is inputstream but at rum time from the actual object that is of type MyInputStream the actual method is called.. thats late binding.. n always calls the correct copy. isn't awesome :-)
0
 

Author Comment

by:motorway
ID: 6912733
But in System.in.read(), System.in refers to an input stream and InputStream has many classes derived from it implmenenting read(). How would it know of which derived class read() should be called. The example you have given
InputStream in=new MyInputStream();
atleast we know it is of type MyInputStream.
But System.in doesn't tell which InputStream to refer. e.g. ObjectInputStream or some other derived class implementing this read() method.
0
 
LVL 16

Expert Comment

by:imladris
ID: 6913123
It doesn't differentiate based on the source code perse. System.in is a reference to a specific object. Each object contains information about its type and methods. The "late binding" is achieved by the object containing enough information to make it possible that the read of "this" object gets executed.
0
 

Expert Comment

by:rashidkamranbs
ID: 6913625
What i just try to depict from the sample code is

1. A reference is important for compiler compiler verifies the function call rite from the reference type.. (correct me if i m not)

2. At run time.. the reference type is forgotten n object is asked to run the method.. n belive me object in its nature is supposed to be a complete entity.. n it contains everything that could be called from the very reference of the object..

so when InputStream's reference cotains MyInputStream stream the read is called from that object..

if it cotains datainputstream .. the read is called from that stream.. n conventionally every calss that ends with InputStream is supposed to be a sub class if InputStream
0
 

Author Comment

by:motorway
ID: 6914639
Following is are the derived classes of InputStream each overriding the read() method.
AudioInputStream, ByteArrayInputStream, FileInputStream, FilterInputStream, InputStream, ObjectInputStream, PipedInputStream, SequenceInputStream, StringBufferInputStream

Now System.in.read() will the call the method of which derived class?
0
 
LVL 19

Expert Comment

by:Jim Cakalic
ID: 6915865
As the previous posts indicate, the key to understanding this is to understand inheritance. Inheritance hierarchies permit concrete objects in the hierarchy with specialized behavior to  be substituted for each other at run time as necessary. There are, in fact, numerous implementations of java.io.InputStream with implementations specific to the source of the data being streamed -- AudioInputStream, ByteArrayInputStream, FileInputStream, StringBufferInputStream, etc. Depending on the source of the input, the correct class is chosen (directly by your application or some other mechanism), and an object constructed to provide access to that data source. From that point forward, due to the common inheritance of each of these classes from InputStream, the rest of your application need not care about the specific source of the data. Your reliance is upon the methods defined by InputStream even though the specific implementation of those methods is in one of the subclasses.

In the case of System.in, it is declared to be no more specific than InputStream because the native platform hosting the JVM may impose varying requirements on which subclass could actually be used. Most of the time, it is likely that this will be a BufferedInputStream wrapping a FileInputStream on a native FileDescriptor. But that doesn't have to be the case. Be assured that when you reference System.in, you are actually referencing some subclass of InputStream. But which one doesn't really matter. In fact, you can find out _which_ subclass is used this way:
    System.out.println(System.in.getClass().getName());

This is likely to return BufferedInputStream. This will probably wrap a FileInputStream which references a FileDescriptor passed by the native OS. This is definitely how it works in my installation. In fact, looking at the source for the System class, it initializes 'in' as:
    new BufferedInputStream(new FileInputStream(FileDescriptor.in));

FileDescriptor.in is a static reference to the standard input stream provided to the JVM by the OS. (Remember that the JVM is a C/C++ native implementation so it shouldn't be too suprising that it gets file descriptors for stdin, stdout, and stderr just like any other C/C++ application.)

Just a clarification that not _everything_ is done using dynamic (aka late) binding. The JVM actually has 4 different instructions for invoking methods. The compiler chooses which instruction to issue at compile time.

invokestatic -- All static method invocation is done using this intruction. It is a form of "early" or static binding. The method the JVM invokes is based on the type of the object reference which is always known at compile-time.

invokevirtual -- This is the real workhorse of polymorphic invokation. The method to invoke is based on the actual class of the object, which may only be known at run time. This is definitely "late" or dynamic binding.

invokespecial -- Sometimes dynamic binding would not yield correct results so the compiler chooses to use invokespecial to force static binding in 3 situations: 1) when calling the compiler-synthesized <init> method during object construction, 2) when calling private methods, and 3) when calling superclass methods directly using the super keyword.

invokeinterface -- Method invokation through an interface requires some special handling because the JVM cannot make as many assumptions about its own internal structures as when dealing directly with classes. This is essential invokevirtual with an extra level of indirection (and overhead).

In summary, class (static) methods are _always_ statically bound (at compile time) whereas instance methods are dynamically bound except in the case of <init> methods, private methods, and methods invoked through super.

If you'd like to know more, here's a link to a great article explaining method invokation:
    http://www.artima.com/underthehood/invocation.html

Best regards,
Jim Cakalic
0
 

Accepted Solution

by:
rashidkamranbs earned 200 total points
ID: 6915913
Here is Your Question motorway
///////////////////////
Following is are the derived classes of InputStream each overriding the read() method.
AudioInputStream, ByteArrayInputStream, FileInputStream, FilterInputStream, InputStream, ObjectInputStream,
PipedInputStream, SequenceInputStream, StringBufferInputStream

Now System.in.read() will the call the method of which derived class?
///////////////////////

Ya just need to concentrate on Inheritance.. read() would be called from the object you instatiate by using new
if its new ByteArrayInputStream() .. read fromt that object..
or if its XXXInputStream the read() from XXiputStream.. cuz if you write something with new.. mean the class is concrete.. n thats gives you 100% surity that it implements read..

i think this should be finished now :)
0
 
LVL 9

Expert Comment

by:Venci75
ID: 7932501
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:
Answered by: rashidkamranbs
Please leave any comments here within the next seven days.
 
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
 
Venci75
EE Cleanup Volunteer
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Are you developing a Java application and want to create Excel Spreadsheets? You have come to the right place, this article will describe how you can create Excel Spreadsheets from a Java Application. For the purposes of this article, I will be u…
Introduction This article is the first of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article explains our test automation goals. Then rationale is given for the tools we use to a…
Viewers will learn about if statements in Java and their use The if statement: The condition required to create an if statement: Variations of if statements: An example using if statements:
This video teaches viewers about errors in exception handling.
Suggested Courses
Course of the Month12 days, 16 hours left to enroll

777 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question