• 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

abstract method throwing exception

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

In InputStream class there is an abstract method:

public abstract int read() throws IOException

What is the functional impact "throws IOException" to this method?

Overriding this method in child class:

1) if I omit "public", I will get error
attempting to assign weaker access privileges; was public

2) If I change int to long, I will get error
[child class] is not abstract and does not override abstract method read() in InputStream

3) But I can omit "throws IOException" with no error.

Moreover, child method can throw some other exception. This code runs with no error:



Is "throws IOException" purly informative with no impact on code compilation/execution?

Regards,
Grzegorz
 
Bartender
Posts: 5478
212
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Here is a very short but clear explanation: tutorialspoint
 
Marshal
Posts: 79475
379
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Grzegorz Wilanowski wrote:. . . there is an abstract method:

public abstract int read() throws IOException

What is the functional impact "throws IOException" to this method?

It means that method and its overriding methods might throw an IOException, and any code calling that method must be prepared to handle an IOException. Remember it is incorrect programming to cause an overriding method to throw an exception that is not thrown by its overridden (superclass) version.

Overriding this method in child class:

I know lots of people say, “child class,” but that term isn't accurate. Inheritance in programming terms is different from inheritance in biological terms or inheritance in money terms. Say, “subclass,” and say, “superclass” instead of “parent class”.

1) if I omit "public", I will get error . . .

An overriding method must be accessible to all code that can access the overridden method. You cannot make the method “disappear” from visibility by omitting its access modifier or making its access more restrictive.

2) If I change int to long, I will get error . . .

An overriding method must return a value that its calling code can handle. The calling code can handle an int, but it cannot handle a long. So you need the same return type (I think) as the overridden method, except that for reference types the return type may be covariant. The return type may be a subtype of the overridden method's return type. There is a concept of methods being return type substitutable, which should appear in the JLS (=Java® Language Specification) here.

3) But I can omit "throws IOException" with no error.

Yes, the overriding method can be an improvement and not throw any exceptions. It is incorrect to throw a new kind of exception. The calling method “expects” the method to run to completion by returning a value or throwing a particular exception, and can handle that. It is incorrect practice to throw another kind of exception because the calling code cannot handle that. Not even an unchecked exception like ArithmeticException. Remember that the compiler goes through the different kinds of exception and the clause throws SomeUncheckedExceptionType has no effect. The fact that the compiler ignores a particular exception declaration doesn't make it good programming.
* * * * * * * * * * * * * * * * * * * * * * * * *
I suggest you try a few programs using InputStream#read(), until you develop antibodies to it and never want to see it again See what happens if you inflict letters like Ł on read(). You will have to work out your own encoding It is a dreadful method to use and you should leave it to things like BufferedReader#readLine() to use read(). That sort of method doubtless uses read(), so you don't have to. But readLine() doesn't handle any IOExceptions, so you will still have to handle that exception.
* * * * * * * * * * * * * * * * * * * * * * * * *
Remember that the overriding method should do what the overridden method does, and mustn't do it worse, but may do it better. That also means the overriding method should comply with all of the specification (=documentation) for the overridden method.
 
Grzegorz Wilanowski
Ranch Hand
Posts: 32
2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
@Campbell

See what happens if you inflict letters like Ł on read()



InputStream is for reading bytes, not characters. Low level eqivalent for reading characters is Reader.
Here is the example of reading Ł




Note: To make it work I need to compile like this

 
Saloon Keeper
Posts: 15630
366
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Most of the time there's no good reason to read individual chars from a stream though, so most Reader implementations should not be used directly. The reason for this is that reading chars using a Reader may split up surrogate pairs.

To read textual data, you should typically use either:

  • BufferedReader, if you handle text one line at a time, or
  • Scanner, if you handle text in another way.

  • One scenario I can think of when you'd want to use a Reader to read a char[] or CharBuffer, is when you're reading a password. That way, you can zero out the password when you're done with it.
     
    Campbell Ritchie
    Marshal
    Posts: 79475
    379
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Grzegorz Wilanowski wrote:. . . InputStream is for reading bytes, not characters. . . .

    Yes. Sorry. My mistake.
     
    Marshal
    Posts: 28264
    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

    Grzegorz Wilanowski wrote:Note: To make it work I need to compile like this



    Starting with Java 18, the default encoding is UTF-8. (That implies that you should really use UTF-8 as your text editor's encoding; it looks like you do that already.)
     
    Grzegorz Wilanowski
    Ranch Hand
    Posts: 32
    2
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Stephan van Hulst wrote:Most of the time there's no good reason to read individual chars from a stream though, so most Reader implementations should not be used directly..



    With Reader, you can also read whole file content into array at once:




     
    Stephan van Hulst
    Saloon Keeper
    Posts: 15630
    366
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Well, what if the file is larger than 1000 UTF-16 code units?
     
    Saloon Keeper
    Posts: 10811
    86
    Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    And... if the file is less than 1,000 characters long that will leave the remainder of the array filled with zeros which println() will attempt to output.
     
    Grzegorz Wilanowski
    Ranch Hand
    Posts: 32
    2
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Stephan wrote:what if the file is larger than 1000 UTF-16 code units?



    Obviously, we need longer buffer or read in a loop.
    But this is what BufferedReader is also doing.
    In one of its constructors you can provide buffer size:


    Carey wrote: if the file is less than 1,000 characters long that will leave the remainder of the array filled with zeros


    That's right.

    Stephan, Carey: based on your remarks I fixed the program:



    data.txt contains two lines
    aaabbbcccddde
    eeff



     
    Stephan van Hulst
    Saloon Keeper
    Posts: 15630
    366
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Grzegorz Wilanowski wrote:But this is what BufferedReader is also doing.



    Which is why I said:

    most Reader implementations should not be used directly


    and:

    To read textual data, you should typically use [...] BufferedReader



    There is no good reason to handle char arrays directly, unless you're working with passwords. Use BufferedReader to read complete lines as strings, or use Scanner to read token strings.
     
    Stephan van Hulst
    Saloon Keeper
    Posts: 15630
    366
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Here is the correct version:
     
    Campbell Ritchie
    Marshal
    Posts: 79475
    379
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Grzegorz Wilanowski wrote:. . . Obviously, we need longer buffer or read in a loop.
    But this is what BufferedReader is also doing.
    In one of its constructors you can provide buffer size:
    . . .

    I know we have strayed from the original question in this thread, but I am not happy about that. That looks like an old‑fashioned way to read a file. I am at a bit of a loss to know why somebody would want to read a text file into a char[] in the first place. But let's try a slightly more object‑oriented way to do it. Read the lines into an object and use that object and other objects to join the lines into one object.
    You are using an old‑fashioned way to create your buffered reader, which has been regarded as legacy code since 2009. Use a Path instead. Also use the “new” (=only fourteen years old) way to close your resources.I presume you are familiar with the idiom in line 8. You could use getBytes(), or serialise the resulting text with a ByteArrayOutputStream to get a byte[] instead.
    I would prefer to use each line as it is read, or read them into a List<String>. Beware of a List if your file is millions of lines long in case you use too much memory.
    You can probably use BufferedReader#lines() and maybe later use flatMap() to get your arrays into one array.

    [edit]Add, “.newBufferedReader()” to lines 3. Have probably left some spelling errors somewhere.
     
    Carey Brown
    Saloon Keeper
    Posts: 10811
    86
    Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
     
    Campbell Ritchie
    Marshal
    Posts: 79475
    379
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Good idea, Carey
     
    Master Rancher
    Posts: 4921
    74
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Or, since Java 11:
     
    Mike Simmons
    Master Rancher
    Posts: 4921
    74
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Carey Brown wrote:


    Hm, this has an issue - it eliminates all the line separators.  A corrected version:

    Or, one more alternative:
     
    Grzegorz Wilanowski
    Ranch Hand
    Posts: 32
    2
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Hi,

    I tried to read 16GB file with the programs from this thread.
    I generated this file in Windows cmd with  command


    This generated file seems to contain only spaces.

    Below are the programs I tested.
    I replaced System.out.print() with doing-nothing writer.print() function from class




    Grzegorz


    Stephan


    Carey1 (two)


    Carey2 (three)


    Mike1 (four)


    Mike2 (five)


    Campbell


    @Campbell code does not compile
    javac Campbell.java
    Campbell.java:11: error: cannot find symbol
           try (BufferedReader reader = Paths.get("data.txt").newBufferedReader())
                                                                                                 ^
     symbol:   method newBufferedReader()
     location: interface Path
    1 error


    Here are the results:



    Only Grzegorz run successfully.
    Then in PowerShell I found it took 28s for Grzegorz program to read this file
    > Measure-Command { java Grzegorz }


    Days              : 0
    Hours             : 0
    Minutes           : 0
    Seconds           : 28
    Milliseconds      : 629
    Ticks             : 286296135
    TotalDays         : 0,000331361267361111
    TotalHours        : 0,00795267041666667
    TotalMinutes      : 0,477160225
    TotalSeconds      : 28,6296135
    TotalMilliseconds : 28629,6135

    Note: for testing I just copy pasted the code from your posts without analyzing it. Maybe there are small improvements to make them run successfuly
     
    Stephan van Hulst
    Saloon Keeper
    Posts: 15630
    366
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    I think it's disingenuous to subject applications that are obviously intended to read multi-line text files to a file that contains 16GB of NUL characters. The only thing you've demonstrated is that your application is the only one that can deal with unrealistic input.

    The only real situation I can think of where more than a gigabyte of text data would be on a single line, is when a large amount of data is serialized to a textual format like JSON or XML and minified to get rid of insignificant whitespace. In such cases, I wouldn't even use BufferedReader or Scanner, but rather a proper JSON or XML deserializer.

    Your comparison would be more valuable if you downloaded a Lorem Ipsum generator and then generated a 16GB text file.
     
    Mike Simmons
    Master Rancher
    Posts: 4921
    74
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Also, if you're no longer actually doing anything with the data, performance will become meaningless.  The actual IO will be much slower than the other concerns.  And, is there any need to use readers and writers at all?  Does the encoding matter, or are you just trying to transfer bytes?  If the latter, there are a variety of other methods possible.
     
    Carey Brown
    Saloon Keeper
    Posts: 10811
    86
    Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Your original code stated that it was reading the whole file into memory, our examples followed that directive. Yep, you proved that doesn't work for huge files as we already knew. It helps to have a clear set of requirements before writing code.
     
    Mike Simmons
    Master Rancher
    Posts: 4921
    74
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    The original code had numerous problems - it wasn't until he started capturing the return value of the read() statement using the actuallyRead variable, that it became more correct.  
     
    Carey Brown
    Saloon Keeper
    Posts: 10811
    86
    Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

     
    Mike Simmons
    Master Rancher
    Posts: 4921
    74
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Let's not forget the most efficient possible implementation, based on the latest test code:
     
    Paul Clapham
    Marshal
    Posts: 28264
    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
    So it took you 30 seconds to read 16 megabytes of data from a disk file. That seems pretty reasonable to me. I wouldn't spend any more time looking for faster code, since the disk hardware limits the speed at which you can read data.

    When my application started to get slow I went out and bought a new computer with much faster disk drives. It was a great success (my old computer was 12 years old) and no amount of rewriting code in the service of "efficiency" would have been anywhere near as good.
     
    Campbell Ritchie
    Marshal
    Posts: 79475
    379
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Grzegorz Wilanowski wrote:. . . @Campbell code does not compile
    . . .

    Sorry; I was trying to write it from memory. You hjave been given the right code.

    . . . Seconds           : 28
    Milliseconds      : 629
    Ticks             : 286296135
    . . .

    I am very surprised that your clock cycles match seconds so precisely at 10MHz.
     
    Mike Simmons
    Master Rancher
    Posts: 4921
    74
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Paul Clapham wrote:So it took you 30 seconds to read 16 megabytes of data from a disk file. That seems pretty reasonable to me.


    It would be poor performance for 16 megabytes.  But the file was actually 16 gigabytes, so yes, it's a reasonable time.

    But, when testing actually copying the file to another file, we can do better.  In particular, Files.copy ends up being about six times faster on my system.  I suspect that's because it's delegated to the underlying hardware, with little intervention from the program.  Using FileChannel's transferTo method can be about three times faster, at least until we get to really big files.  An old-school InputStream-to-OutputStream copy that we would have written before Files or FileChannels classes were available, that is still about twice as fast.  Well, results vary.  But, considerable improvement is possible.

    Gives this output:
     
    Carey Brown
    Saloon Keeper
    Posts: 10811
    86
    Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    My stats. File_copy didn't do too well for me. Java 20.0.2, Windows 11.
     
    Carey Brown
    Saloon Keeper
    Posts: 10811
    86
    Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    @Mike, were you running under Windows or Linux?
     
    Mike Simmons
    Master Rancher
    Posts: 4921
    74
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    No.

    (MacBook Pro)

    And you?

    And, do the stats hold up (roughly) under repetition?  Mine generally do, though the high FileChannel.transferTo() on the last run may have been an outlier.
     
    Carey Brown
    Saloon Keeper
    Posts: 10811
    86
    Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Windows 11. Yes, the numbers hold up under repetition. I shut down all extraneous programs and ran it from the command line instead of Eclipse.

    I also tried copying the program to an SSD 2TB M.2 instead of the SATA drive. Overall the numbers were 8-10 times better but their relationship within the group of benchmarks stayed roughly the same. Still not as fast as your numbers.
     
    Grzegorz Wilanowski
    Ranch Hand
    Posts: 32
    2
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Stephan van Hulst wrote:Your comparison would be more valuable if you downloaded a Lorem Ipsum generator and then generated a 16GB text file.



    I repeated test for Moby-Dick ebook.
    The first program (renamed to honor Stephan and Carey contribution    ) is still the fastest:

    > Measure-Command { java GrzegorzStephanCarey }|Select-Object "TotalMilliseconds"

    TotalMilliseconds
    -----------------
            304,1668


    > Measure-Command { java Stephan }|Select-Object "TotalMilliseconds"

    TotalMilliseconds
    -----------------
            327,9678


    > Measure-Command { java Carey1 }|Select-Object "TotalMilliseconds"

    TotalMilliseconds
    -----------------
            401,4525


    > Measure-Command { java CareyMike }|Select-Object "TotalMilliseconds"

    TotalMilliseconds
    -----------------
            407,3193


    > Measure-Command { java Mike1 }|Select-Object "TotalMilliseconds"

    TotalMilliseconds
    -----------------
            326,9551


    > Measure-Command { java Mike2 }|Select-Object "TotalMilliseconds"

    TotalMilliseconds
    -----------------
            490,6012



    Carey Brown wrote:Your original code stated that it was reading the whole file into memory, our examples followed that directive. Yep, you proved that doesn't work for huge files as we already knew.


    This is still true. When I concatenated Moby-Dick multiple times to get 1.3GB file, I was still observing OutOfMemory in programs others then GrzegorzStephanCarey.
     
    Stephan van Hulst
    Saloon Keeper
    Posts: 15630
    366
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    On a side-note: while it doesn't really matter that much when you're testing I/O operations, when you're benchmarking an application you REALLY shouldn't be implementing your own timers, especially not using currentTimeMillis() or any of its ilk.

    Instead, use a proper benchmarking framework like jmh.
     
    Mike Simmons
    Master Rancher
    Posts: 4921
    74
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Yeah, I did a quick-and-dirty implementation to make it very easy for anyone to run on their own machine with minimal setup.  But for greater accuracy and reliability, something like JMH is preferable.  My mini-framework is ignoring a host of issues.
     
    Mike Simmons
    Master Rancher
    Posts: 4921
    74
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Grzegorz Wilanowski wrote:When I concatenated Moby-Dick multiple times to get 1.3GB file, I was still observing OutOfMemory in programs others then GrzegorzStephanCarey.


    That's fully expected for most of those methods, as they obviously read the whole file into memory, just like your original program.  However, that shouldn't happen for  Stephan's code, which only failed your previous attempt because there were no line breaks, and consequently reading one line was equivalent to reading the whole file.  Does that one really throw an exception for you using the moby dick text?  What stack trace do you see?  Stephen's version also has the advantage that it successfully writes the entire file.

    I see I neglected to include Stephen's code in my previous comparison - sorry about that, Stephan! It looks like it behaves pretty much like the Files_lines_forEach that I did test.  They're slow compared to mot of the other methods tested, and it becomes tiring to wait for larger-size files to complete (which is why I was skipping them for later tests) - but if you give them time, they do complete successfully, even for the 16 GB file copy.
     
    Consider Paul's rocket mass heater.
    reply
      Bookmark Topic Watch Topic
    • New Topic