• 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

compiler error regarding method

 
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello everybody !!!


Given the code below:


package JavaLibrary1;
import java.io.*;

public class Print {
public Print(){ System.out.println("HELLO");};
public static void print(Object obj) {System.out.println(obj);}
public static void print() {System.out.println(); }
public static void printnb(Object obj) { System.out.print(obj); }
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
package chapter8ex3;
import static JavaLibrary1.Print.*;


class Derived {
int x=9;
// void print(int x){} (1) if I compile with this method its OK
void print(){
print(x); //(2) gives complier error
//JavaLibrary1.Print.print(x); (3) if I’m explicit its OK
}
}

public class Chapter8Ex3 {

public static void main(String[] args) {
Derived d=new Derived();
d.print();
print("HH"); // (4) it compiles
}
}

I have the following Q:

When I compile the code I get an error at line (2) with a message saying :
„print() in chapter8ex3.Derived cannot be applied to (int) print(x);
1 error”
Line (4) its OK

However if I’m explicit as in line (3) it compiles.
I thought is has something to do with the fact that methods print() and print(x) have the same name
and the latter is in the scope of the former
I looked up in JLS 7.0 and I found this under Shadowing 6.4.1:

* A declaration d of a method named n shadows the declarations of any other methods
named n that are in an enclosing scope at the point where d occurs throughout the
scope of d.
*/

But if this is true then line (1) should give an error but it doesn’t !!!


Thanks
 
Ranch Hand
Posts: 479
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I am going to make a guess here -- my guess is that you think the import statement causes your class 'Derived' to extend your class Print.

The import statement does not do that -- all import does is allow you to use a class name such as Print without entering its fully-qualified name; in this case, that's JavaLibrary1.Print.

So you are not invoking the print method in Print; the only print() method available to Derived is the one that is invoking print, i.e., the closest match it has is invoking itself. It cannot do that if it passes in an int argument, because the only print() method available to it doesn't take any arguments. Line 1 works because it defines itself to take the int argument. And if you fully-qualify the class and method, then it can find it (since it's static) (if the method in Print were not static, that would still be a compile-time error.

If you want Derived to extend Print so that Derived objects inherit Print's methods, then your declaration of Derived should be:

class Derived extends Print

rc
 
Dan Craciun
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The class Derived was extending another class .I did not include the class because it was not relevant.
Also look at line (4) in method main() it works fine. So the method print(Object) from JavaLibrary1 package is visible in main() and any other method excluding
a method with the same name but with different arguments.
 
Ralph Cook
Ranch Hand
Posts: 479
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I suppose what this really illustrates is the danger of making assumptions about the question. I realize now you didn't even say what the error was.

This also illustrates why those of us who volunteer our time here often want small, self-contained examples. Without one, we are forced to make assumptions about what your code does, what extends what, and how much you know. It wastes some time on occasion.

I have learned that print(int i) will invoke print(Object o) (I tried it with code of my own); I try not to depend on autoboxing or whatever that's called, and didn't realize it would even work.

Whether a method is "visible" does not mean it is being invoked. You are having a compile-time problem with a method invocation, but you think the superclass is not relevant. Good luck figuring this out; I don't think I can help you.
 
Dan Craciun
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Ralph,

its clear to me as I mentioned on my first post that the error is due to the fact that the methods print() in class Derived and the call to print(x) in method print() have the same name. If I put the method print(x) in any other method or I rename the method print() to printx() the code compiles.

This is similar to name collision for classes . If I define a class Vector and if I import java.util.* (which has also a class Vector) and I call the constrcutor Vector() I get an error because I have two constrcuctors with the same name. I can solve this if I explicitly import java.util.Vector.

My question was : Where in Java Language Specification the issue of "collision" between methods with the same name is mentioned? As a said in my first post the only thing I could find is Shadowing , but the explanation there was not clear. I provided a counter example.
 
Dan Craciun
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
in my first post I mentioned the compiler error.
I did not add the superclass to te code because I tried to keep the example as short and as simple as possible. With or without the supperclass the error is the same.
 
Ralph Cook
Ranch Hand
Posts: 479
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This is why we ask for a "self-contained" example. Post the fewest lines of code that someone else can put through a compiler and illustrate your problem. I'm sure the problem is clear to you as you explain it, but it is not clear to me.

Note that "fewest" does not mean "cut out things that you decide are irrelevant". It means cut out anything not needed to illustrate the problem.

rc
 
Dan Craciun
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The code is:

[highlight=Java]

package JavaLibrary1;
import java.io.*;

public class Print {
public Print(){ System.out.println("HELLO");};
public static void print(Object obj) {System.out.println(obj);}
public static void print() {System.out.println(); }
public static void printnb(Object obj) { System.out.print(obj); }
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
package chapter8ex3;
import static JavaLibrary1.Print.*;
[highlight=Java]

class Foo {
int x=9;
void print(){
print(x); //(2) compiler error
}
}

public class Chapter8Ex3 {
public static void main(String[] args) {
Foo d=new Foo();
d.print();
print("HH"); // (4) it compiles prints HH
}
}


AND the same code except method print() changed



class Foo {
int x=9;
void print(){
JavaLibrary1.Print.print(x); (3) if I’m explicit its OK prints 9
}
}



The first gives compile error the second works also the third:



class Foo {
int x=9;
void printx(){
print(x); (3) it compiles if I change name of method print() to printx()
}
}



clearly its a name conflict in the first piece of code between method print() and method print(x).

I looked up in JLS and the closest thing I found is:
"A declaration d of a method named n shadows the declarations of any other methods
named n that are in an enclosing scope at the point where d occurs throughout the
scope of d."
 
Ralph Cook
Ranch Hand
Posts: 479
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Dan Craciun wrote:The code is:

[highlight=Java]


We use bracket-code-bracket tags here; see the 'code' button on the posting interface.

Dan Craciun wrote:




This is an error because the compiler cannot find a print(int n) method to invoke. It evidently does not regard the static import of a method print(Object o) as compatible.

Dan Craciun wrote:


This is not an error because the compiler found the print(Object o) method from the static import.

Dan Craciun wrote:


AND the same code except method print() changed



The first gives compile error the second works also the third:



clearly its a name conflict in the first piece of code between method print() and method print(x).

I looked up in JLS and the closest thing I found is:
"A declaration d of a method named n shadows the declarations of any other methods
named n that are in an enclosing scope at the point where d occurs throughout the
scope of d."



So if x is an int and you invoke print(x), the compiler does not find the method imported wtih a static import for print(Object o).

I had to look up static imports; it was an animal unknown to me. It appears that, although Java will autobox the int to an object if the method is within normal scoping rules, it will not find it on a static import.

My two reactions: (1) So what? , and (2) I'm glad we don't do this kind of stuff in our shop. The java page I found on static imports recommends that you practically never use them (and only for cases of multiple uses of constants), and if I saw this in code that I had to read I would suspect the author of seeing how un-usefully complicated he or she could make things.

Your original post said that the compiler should find an error if the method in the class Derived in that example had an int argument. I have no idea why you say so; it is invoking itself with the exactly argument type it is declared with, quite unlike any of your error scenarios.

So the only thing I find that might be regarded as unusual (by someone else, not me!) is that the automatic finding of a print(Object o) method for an integer argument is done for normal scoping rules but not on a static import. I don't know if that's a bug or not, but frankly, my dear, I don't give a darn.

 
Dan Craciun
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi

I have a few remarks

Again I want to emphasize that no sane person would write code like this, the only thing I'm trying to figure out (for the sake of learning) is why the program behaves the way it does

Now for the code below you said it worked because print("HH") calls print(Object). It works also with a call like print(3), so the program finds print(int) to invoke



the same here:




and also here:



and here:


BUT NOT HERE:





So my conclusion from all these "tryouts" is that in with static imports method print(Object) is available EXCEPT when it is called from a method with the same name (i.e print() or print(String) etc)

I apologize if my early posts wre not that clear.
 
reply
    Bookmark Topic Watch Topic
  • New Topic