Sorry, I did not notice - compiler probably is bound to generate bridge
method which makes cast to Vector2D
But I am free to pass an instance of any conforming type.
I don't think so. At least not without the compiler warning about
unchecked casting. If you have
Vector2D v;
you can only pass Vector2D instances to v.add(...). If you have
V v;
where V is actually Vector2D, you can only pass V instances to
v.add(...). But V is actually Vector2D, so it is OK.
Except that super calls are dispatched by VM with no help needed from a
programmer.
The thing is that prohibiting inheritance is a feature here, not a
drawback. This is because inherited behavior is most likely to be wrong.
(as with Vector.zero() or Serializable.readObject() (if readObject was a
static method returning the read object)). If this is not the case, then
it would probably not be the best choice to use this feature.
Right, but the difference is that super calls are not subject to 'human'
errors (what happens if inheritance chain has been updated? you have to
manually review all subclasses and repair static calls)
This is not a new problem. You have the same problem with current static
methods, if you call a static method of a superclass. It might be useful
to have some static analog of the 'super.instanceMethod()' construct,
regardless of my proposal.
or omit it so then you impose different context. Namely, pretend
to be able to read remote files while you are not. And one more
question:
//client code
Stream s = new AudioVideStream(..);
read10Bytes(s);
public byte[] read10Bytes(Stream s) { if
(!Stream.isReadable(file)) //how would you dispatch it? There is
no way I suppose
This would be a compile-time error, since isReadable() is abstract
in Stream.
This is really bad
Then actually your statics will be usable only
when you know exact type you want to work with.
And with generics and with dynamic loading.
Still, you have to redefine static method so that it is _usable_ for
every type, but _used_ only when exact type is of special interest which
encourages too strict typing.
Again not sure what exactly you meant. In the example of AudioVideoCodec
I provided, the isReadable() method was only required to work with
AudioFiles.
Ok, probably now I understand fully your
concept. I'd uphold my opinion that this is not so good. Here is a quick
rundown why I think so: 1. Problem it solves can be solved in other
ways, without any need for special syntax/semantics/language or VM
changes (like Vector)
Each problem can be solved in other ways. You could argue that we don't
need generics, because every problem can be solved without them. The
question is how concise and readable the solution is. Unnatural hacks are
IMO very bad for code readability.
2. It is not clear how it would/should behave even
for problems it is supposed to solve
(code: public <T extends Foo> void doSth(T t) { T.staticFromFoo(); }
public class Bar extends Foo { public static void staticFromFoo()
{...};}
what should it bind to? If Foo, what if it is passed a Bar instance in
runtime?)
It should bind to whatever type T represents. That is why reified
generics are necessary. The bytecode of doSth() would contain the
information that the staticFromFoo() method of T is called, where T will
be specified at runtime (though I suspect that this could be optimized at
link-time).
3. It encourages bad code smell, that is: coding with the most specific
type instead of coding with interfaces
How? Did we have an example of this? If yes, I probably missed it.
4. It solves relatively infrequent problems
The problem with serialization frameworks is infrequent. I suspect that
the other problem with generics may be quite frequent.
5. It is error prone - developers will have to study
all subclasses to spot what should be changed after any superclass has
changed
I don't see any special relation of this problem to the proposed feature.
It is always bad if you depend on the implementation of the superclass
rather than on the interface only. This feature does not encourage you in
any way to depend on the superclass. If you are referring to the problem
of calling superclass methods on superclass's class literal
(MySuperClass.staticMethod()), I already argued that this is not a new
problem.
6. It makes developers implement this static heritage over and
over, even when it is not needed
It is designed for cases when it _is_ needed. I admit that someone could
be tempted to use it inappropriately. But almost anything can be misused.