• 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

Something interesting about two overloaded constructors of FileInputStream

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

As I was reading Mala Gupta's book, I came to a page where there is an interesting discussion on a scenario where there are two valid, overloaded methods but where the compiler will get confused and then report a compile-time error in response to certain inputs.

Here are the methods.



I quote from the book: "... but an issue arises when you try to execute this method using values that can be passed to both versions of the overloaded methods. In this case, the code will fail to compile ..."

Here is the code showing the use of the methods:



Because an int literal value can be passed to a variable of type double, both methods are acceptable candidates for literal values 2 and 3, and therefore the compiler fails to decide which method to pick.

This is where I get confused when I take the above concept with me and dive further into the book to the final chapter, the chapter of exceptions. There, the writer introduces from Java 7 API two overloaded constructors of FileInputStream.

1. public FileInputStream(String name) throws FileNotFoundException {.....}
2. public FileInputStream(File file) throws FileNotFoundException {.....}


The writer also says that, according to the Java 7 API source code, here is the definition of the version that takes a String object as the argument:



Now, if "name" is indeed null, this(name != null ? new File(name) : null); evaluates to this(null); which in turn is equivalent to invocation of FileInputStream(null); but then both FileInputStream(String) and FileInputStream(File) become possible choices to be invoked with a null value. Does it not give rise to ambiguity? So, isn't there a compile-time error for that?

I do understand that eventually a FileNotFoundException is raised, but it is a separate issue which comes later. How is the ambiguity resolved before that?
 
Bartender
Posts: 2236
63
IntelliJ IDE Firefox Browser Spring Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If you pass null like below, the compiler will indeed complain about ambiguosity.But if you have your null in appropriate varialbe, the compiler will not complain. The type of the variable determines which constructor is chosen.If you cast a null to appropriate type (yes, you can do this) you can help the compiler to choose a version of constructor (or method).
 
Mohammad Ali Asgar
Ranch Hand
Posts: 39
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks Pawet,

Yes, I have realized that. In fact, as I have come to know, if "name" is null, then

this(name != null ? new File(name) : null); evaluates to this((File)null); not this(null);

As per JLS: http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.25-300-C

if one of the second and third operands is of the null type and the type of the other is a reference type, then the type of the conditional expression is that reference type.

That is why null is type-cast into (File)null. So, there is no ambiguity and FileInputStream(File) is chosen by the compiler.

And, lastly, this((File)null) is analogous to
File file = null;
new FileInputStream(file);
 
Sheriff
Posts: 11604
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
As you already discovered, it's all about using the conditional operator. The conditional operator evaluates to a certain type based on 2nd and 3rd operands (the 1st one always have to be a boolean). So the call to the constructor this(name != null ? new File(name) : null); is equivalent to File file = (name != null ? new File(name) : null); this(file); and that's why you don't have the compiler error.

Can we use the equivalent in the constructor? Why (not)?


And what happens when the types of the 2nd and 3rd operands are different, like in this example. What type will the method need to have to make the code compile (if possible)?


PS. That was an excellent question (and analysis), have a cow for that!
 
joke time: What is brown and sticky? ... ... ... A stick! Use it to beat this tiny ad!
a bit of art, as a gift, that will fit in a stocking
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic