tags:

views:

129

answers:

1

Hello,

There is a "NameAndType" structure in the constants pool in .class file. It is used for dynamic binding. All methods that class can "export" described as "signature + return type". Like

"getVector()Ljava/util/Vector;"

That breakes my code when return type of the method in some .jar is changed, even if new type is narrower.

i.e: I have the following code:

List l = some.getList();

External .jar contains:

public List getList()

Than external jar changes method signature to

public ArrayList getList().

And my code dies in run-time with NoSuchMethodException, because it can't find

getList()Ljava/util/List;

So, I have to recompile my code. I do not have to change it. Just recompile absolutely the same code!

That also gives ability to have two methods with one signature, but different return types! Compiler would not accept it, but it is possible to do it via direct opcoding.

My questions is why? Why they did it?

I have only one idea: to prevent sophisticated type checking in the runtime. You need to look up to the hierarchy and check if there is a parent with List interface. It takes time, and only compiler has it. JVM does not.

Am I right?

thanks.

+2  A: 

One reason may be because method overloading (as opposed to overriding) is determined at compile time. Consider the following methods:

public void doSomething(List util) {}

public void doSomething(ArrayList util) {}

And consider code:

doSomething(getList());

If Java allowed the return type to change and did not throw an exception, the method called would still be doSomething(List) until you recompiled - then it would be doSomething(ArrayList). Which would mean that working code would change behavior just for having recompiled it.

Yishai