Prev: Java work from home. Remote (telecommuting) jobs in Java.
Next: Zip question: Where are all the extra characters coming fromupon unzipping?
From: rossum on 20 Oct 2009 11:45 On 20 Oct 2009 14:10:56 GMT, Andreas Leitgeb <avl(a)gamma.logic.tuwien.ac.at> wrote: >I'm not familiar with that idiom, but an uncrossed "t" is hardly a "t", >but rather an "l" (well, depending on the font, perhaps). With that, >the question of enforcing c'tors is even less "compelling" than making a >"t" a real "t". "Dotting all the i's and crossing all the t's" is an idiom for making sure that all the small details are correct. rossum
From: Andreas Leitgeb on 20 Oct 2009 12:56 rossum <rossum48(a)coldmail.com> wrote: ><avl(a)gamma.logic.tuwien.ac.at> wrote: >> I'm not familiar with that idiom, but an uncrossed "t" is hardly a "t", >> but rather an "l" (well, depending on the font, perhaps). With that, >> the question of enforcing c'tors is even less "compelling" than making a >> "t" a real "t". > "Dotting all the i's and crossing all the t's" is an idiom for making > sure that all the small details are correct. Thanks!
From: Daniel Pitts on 20 Oct 2009 15:12 Tomas Mikula wrote: > On Mon, 19 Oct 2009 16:22:56 -0700, Daniel Pitts wrote: > >> Tomas Mikula wrote: >>> On Sun, 18 Oct 2009 19:19:55 -0700, Peter Duniho wrote: >>> >>>> Tomas Mikula wrote: >>>>> I have searched this group for "abstract static methods" and found a >>>>> couple of threads, but I think none of them was discussing the kind >>>>> of semantics I am going to describe. As you might have guessed, I >>>>> believe it would be useful :). [...] >>>> You aren't the first. However, in C++, C#, Java, and languages like >>>> them, you simply are never going to have methods that are both virtual >>>> and static. And since abstract implies virtual, that rules out >>>> abstract static methods too. >>> I'm not talking about virtual static methods. In this case, abstract >>> would not imply virtual. My second use case could most probably be >>> accomplished in C++ by Concepts (though Concepts didn't make it to C+ >>> +0x). In fact, it is achievable with current C++ templates, only >>> without compile time checking --- it is possible to call >>> T::staticMethod() where T is a template parameter. >> C++ Template programming provides compile-time polymorphism. In Java, >> you don't have Templates, so there is no similar approach. >> >> If you think you need a "static" method to be overidden, then you really >> need to have a non-static method, on a polymorphic object. > > I rather think that sometimes I need to enforce that the static method > _will_ be overridden in every subclass. Non-static methods do not enforce > overriding, because they inherit the implementation from superclass. Note > that I don't want that the following example outputs "B", as was proposed > in some other discussions about abstract static methods. > > class A { > static void f(){ System.out.println("A"); } > } > > class B extends A { > static void f(){ System.out.println("B"); } > } > > A a = new B(); > a.f(); Why do you want to enforce a static method to exist in children? I can think of no good reason for it. -- Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
From: Tomas Mikula on 20 Oct 2009 15:18 On Tue, 20 Oct 2009 14:07:22 +0000, Andreas Leitgeb wrote: > Tomas Mikula <tomas.mikula(a)gmail.com> wrote: >>> > The idea here was to automate the reflection. >>> Sorry, that is a non-starter. > >>> If you don't know the class at compiletime, then neither does the >>> compiler, so there's nothing the compiler could possibly do for you >>> beyond what it already does, namely write bytecode to have the JVM >>> check it all at runtime. > >> In my original post I noted that the use of Class's newly introduced >> method >> <T> Implementation<T> asImplementationOf(Class<T> clazz); >> would have the restriction that the type T is known at compile time. > > The syntax you use suggests, that the result of that function would be > some object (yes, an instance, a bit like the Class-Objects), that > offers methods to call the dynamically loaded class' static methods... > > class MyBase { > static abstract void foo(); > } > class MyImpl extends MyBase { > static void foo() { System.out.println("Called me"); } > } > use: > Implementation<MyBase> impl = Class.forName("MyImpl"). > asImplementationOf(MyBase.class); > impl.foo(); // prints "Called me". > Implementation<MyBase> implFail = Class.forName("MyBase"). > asImplementationOf(MyBase.class); > // the preceding line throws error, because MyBase doesn't // > *implement* the abstract method foo(). > > Is that your intention? Yes. > If yes, please read on; If no, the rest of my posting may be moot. > >> In this case, the compiler can generate the bytecode to check if the >> 'this' class implements T. > > I think, that whenever such a hierarchy of static methods is wanted, an > alternative solution with virtual (i.e. non-static) methods is easily > available with (if at all) only small cosmetic "up to taste" drawbacks. > >> - it requires to get an unnecessary instance (not so bad yet); - >> getting this instance requires reflection > Reflection already starts at Class.forName(...) and if I understood > correctly, you didn't intend to replace that call. Correct. > >> - using reflection for getting an instance requires conventions >> which cannot be checked at runtime (such as the presence of some >> particular (e.g. no-arg) constructor) > > Of course it *can* be checked *at runtime*! Sorry, I meant compile time. But they still can't be checked _elegantly_ at runtime. > See Class.newInstance(). > If that throws an Exception, then there obviously was some problem in > the attempt to call the no-args constructor of the class. This simple > line: > MyBase mb = (MyBase)Class.forName("MyImpl").newInstance(); > already checks *at runtime*, that > - the named class is loadable > - the named class has a no-args c'tor - the no-args c'tor succeeded > (did not throw an exception itself) - the thusly construed instance is > castable to "MyBase". I was aware of this simple and only example where the convention can be checked at runtime quite concisely. What if I want to use another constructor and, say, two static methods. Things get a little messy. >> Furthermore, if I forget to override pseudoStatic() or realStatic() in >> a subclass, I will get the realStatic() from superclass, which is not >> what I want. > > If you forgot to override pseudoStatic(), then the derived class will > not even compile (assuming it is not declared as abstract, itself). For > non-static methods, all those mechanisms are already well worked out. It will compile. Consider abstract class A { public abstract void pseudoStatic(); } class B extends A { public static void realStatic(){...} public void pseudoStatic(){ realStatic(); } } class C extends B { // If I forget to override pseudoStatic, I get the one from B. // If I provide pseudoStatic, but not realStatic, // I get realStatic from B. } So I really need to provide them both, but the compiler doesn't force me to do so. I could make the realStatic private to reduce the danger to half, but then I wouldn't be able to call it the classic way C.realStatic (). > Overriding realStatic() is not an issue, as you just wouldn't define it > in the base class, and so the call to realStatic() in the overridden > pseudoStatic() would fail at compile time, until you either add a > realStatic() method, or just did something else in the (enforcedly > existing) implementation of pseudoStatic(). The same applies here. > >>> I don't think, that calling static methods on dynamically >>> named classes is worth such deep changes as you seem to have in mind >>> for this task. >> The good thing about it is that the changes are not real changes, just >> extensions. So far I think they are all backward compatible with >> current specification. No old code would be broken if these extensions >> are introduced. > > I do not even doubt that. > It's just that these extensions add much too much fuss and doesn't seem > to gain a substantial advantage in return. Okay, thank you for the opinion. I still find the concept of enforced static methods/constructors and the ability to call them on generic type parameters very useful. But I may be biased towards my recent needs. I would of course not insist on the syntax/API proposed here. It was just the first idea that seemed quite consistent.
From: Tomas Mikula on 20 Oct 2009 15:36
On Tue, 20 Oct 2009 12:12:31 -0700, Daniel Pitts wrote: > > Why do you want to enforce a static method to exist in children? I can > think of no good reason for it. And I also want to enforce constructors. I provided two use-cases. 1. serialization frameworks. It is already required that a Serializable class has a no-arg constructor. But this is not required at compile time. Other variant is to require some particular constructor or a creator static method, such as MyClass.readObject(ObjectInputStream) (though this method is non-static and not mandatory in Serializable). 2. For calling static methods on generics. My example was abstract class Vector<V extends Vector<V>>{ /** returns a zero vector */ public abstract static V zero(); } Then somewhere else I would like to use code as this: MyClass<V implements Vector<V>> { // 'implements' is not valid here now ... V v = V.zero(); // not possible now ... } |