Andreas said:
There isn't any real distinction between marker interfaces
like Cloneable and "normal" interfaces.
Lack of methods seems like a pretty big distinction between Cloneable
(and Serializable) and "normal" interfaces.
And any other type of compatibility inconsistent with the
instanceof-operator is right out of question, anyway.
Of course instanceof would continue to use the same semantics of
not-null-and-is-assignable-to that it currently has. It's just
assignable-to that might be a bit broader.
Yes, yes, yes! Not sure, if you got that idea yourself, or
from reading <
[email protected]>.
(in case google distorts it: "slrngfmc50.4jb.avl" is the part
before the "at")
Eh -- I don't read using Google, and you don't appear to have posted
this using Google, so why would Google distort it?
As I brought it, it would subsume the functionality
of proposed typedefs plus add some more useful usecases.
With the added proviso that extensions of final classes can't see their
protected fields and methods. Essentially, "protected == private if the
class is final" would be maintained.
e.g. any negative value would have to be trivially smaller
than any unsigned value, and an unsigned value beyond the
range of the other signed value would have to be trivially
always larger. That is grossly unlike C's behaviour for
operators with mixed-signedness operands. And that isn't
yet all to it (what sign would be the result of mixed-
signedness addition?)
A can of worms best avoided. Make the ubyte type not work with other
integers at all without an explicit cast, or else do the usual Java
thing -- an implicit widening conversion to int and use int's arithmetic.
Sounds cool, principially, but I don't like to add a "line noise
character" for that feature, but rather some keyword.
Verbiage alert. This is a slight modifier that would be very common on
reference declarations, so it would be good to economize on typing or
visual clutter where it was used.
It wouldn't be possible to create arrays of non-null types,
unless there'd also be syntax to pre-initialize the elements.
String[] array = new String[50];
for (...) { ... populate array ... }
String*[] noNullsArray = array; // Runtime check that no element
// is null gets generated here.
String*[] another = {"Foo", "Bar", "Baz"};
Of course we could get into hairiness with noting whether the array
reference itself can be null:
String*[]* -- which * means which?
Maybe better to use
String[*], String*[*]. The * in brackets then clearly refers to the
array, and the * on String clearly refers to the element type, so the
former is an array reference that cannot be null whose elements can be null.
Arrays are something of a corner case anyway, since they should usually
Really little gain, given that most of the times one really should
do something with the value (especially in catch-blocks), and in
other cases, the name of some parameter gives a hint as to what
is expected there, (and may be used as such by overrides).
The cases I was thinking of are e.g.
catch (IOException) {
// Error recovery that is independent of the exact details of
// the exception
}
foo.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent) {
doIt(); // Independent of the event object, and nobody
// will ever subclass and override this!
}
}
Also, for unused method-arguments, the name is usually referred to
by the javadocs. You do javadoc your methods, don't you?
My anonymous inner class actionPerformed methods?
You're joking, right?
May be useful in a few special cases, but sends a wrong message
No, it does not.
One shouldn't really use HashMap<...> typed variables in one's
code, but rather Map<...> typed ones for more flexibility lateron
(just assign a TreeMap instance to the Map variable instead of a
HashMap and don't bother with having to change all the variable's
types.)
I'm just asking for
Map<Key,Value> map = new HashMap();
The proposal would encourage use of:
HashMap<...> hashMap = new *(...);
The really-abbreviated new would of course be used for cases where the
types were the same.
StringBuilder sb = new(10);
foo.addActionListener(new() {
public void actionPerformed (ActionEvent) {
...
}
}
etc.
Obviously, the type in the constructor name is not redundant when it's
not the same type as the reference!
which would be a bad thing.
If someone is determined to write bad code, they will.
Indeed, for abstract classes' constructors: public is equivalent to
protected. So public could be mapped to protected for those. I see
no gain from that mapping, and even much less gain from demanding
programmers to change "public" to "protected". Since they are in
that case equivalent, it means it doesn't really narrow accessibility.
(which otherwise is a generally good thing to do, of course)
It just seems pointless.
On the flip side, the compiler's not permitting "abstract final" is
silly, since it would be useful for making one of those static-utilities
classes be both uninstantiable and unsubclassable. As things stand, you
have to put a private no-argument constructor in, which says the same
thing as "final" but in a much more verbose and less readable manner.
It is still good to *be able to* limit a process' memory footprint.
It just shouldn't be limited by default and then also too low (as it is now)
I guess, you meant it that way, too.
Yes. -Xmx would still work, but omitting it would result in the Java app
having the same memory limits as native code, whatever those might be
depending on hardware and OS.
But it would have to have some gc/allocator tuning to keep a not too low
and not too large amount of slack space. If heap size much bigger than
live objects, return some to OS; if not much bigger at all do an inc GC,
then grow if need be (and the bigger it gets, or if OS won't let it grow
any more, be more eager to do a full collection); etc.
That's the wrong approach.
Whoa! Why the sudden hostility?
No. Nothing that I have said is wrong.
I'm aware of these (and that they don't seem to work all that well --
they seem to actually behave more or less the same as WeakReferences).
But there are other things possible, too. For example, changes of
algorithm/strategy in parts of the program (e.g. use slower but less
storage-intensive methods to do some key piece of work if memory gets
tight). Lots of those kinds of responses (including "alert the user"!)
are not easily done by using SoftReference but are easily done by using
a listener.
Best to support both approaches, each useful for different things.
There is no sense for "SwingUtilities.invokeLater" to declare to throw
any checked exceptions. Unlike C's "fork", the SwingUtilities.invokeLater
doesn't "return twice": all the created threads don't know nuts about
SwingUtilities.invokeLater.
I think you've misunderstood me. The point was that this would be a
corner case, where the compiler would think that an exception could be
thrown somewhere where it actually wouldn't occur for exactly the
reasons you state.
This is an entirely different situation, and yes, that one does
make sense. Such a custom block structure would most likely not
take a Runnable, but rather a
"HaroldsRunnable<ThisException,ThatException,...>"
Having to declare all kinds of types like that explicitly would be a
pain, though. Having block literals that implicitly have such types
would be much nicer. (The types would still show up explicitly in method
argument declarations when programming to receive such things, though.
But that's hardly avoidable.)
I think there are a big lot of caveats that need to be dealt
with. It starts, where the Compiler needs to know, just what
is the Element-type. It can infer it in the "assignement-RHS"
case, but not safely elsewhere.
Why not just least common denominator? The most specialized type that
still is assignable from all of the types of the element expressions.
If the previous item has a solution, then this one can
easily be done by appending .toList() to the array-literal.
Wasteful in the extreme. Not just one intermediate object, but probably
actually N+1, and a whole extra O(N) copy of the collection.
Adding an Iterable-accepting constructor to the non-Map collections
seems ideal.
The Rectangle makes me feel uneasy about it. As a Pair of pairs,
it probably could no longer directly access its own data, but
would have to maintain two pointers to separate Dimension instances.
But then again, I may be wrong...
The JIT could work its usual magic on ones that were used and discarded
locally.
But much yuckier syntax ... I don't see the gain at all.
Not versus "real" closures, I'm sure. But it might pay off to think of
ways to sneak them in by the back door, so to speak.
How would this behave with Boolean x= new Boolean(false); ?
The object is not null, but means false (after auto-unboxing).
If the object is convertible to boolean, the boolean value is used. If
it's not, it's nullness is used. If it's a non-boolean primitive, it's
an error, or else its zeroness is used. (That last gives more or less
the same semantics found in C and C++, but without having a general
convertibility to boolean in any context, only the ternary operator.)
Another entirely different approach could be an
"exemptfromtry { ... }" block inside the try-block.
Oh, my God. Uggg-leee!
Quite a controversial topic.
Quite.
I could have sworn that I saw some static method of some
utility class that returned the original hashCode for any
instance.
Yes, but it really belongs as a final instance method of Object.
Even if it doesn't exist, I think
a static method in a reflection-related class would be a
better approach, than adding it to Object.
Why? Surely not some "adding things to Object is expensive" notion? This
wouldn't add a *field* or anything, after all, and one more method is
just one more entry in one more method table in one place.
In fact the default Object hashCode could then be reimplemented to just
call identityHashCode. There'd hardly even be more bytecode in the
Object class -- only the same amount that results from adding
int foo () {
return bar();
}
to a class.
Never so far found a need for that.
Well, I have. Lots of times.
The existence of IdentityHashMap is proof that someone at Sun also
thought that such a thing could be useful. They just didn't generalize it.
Is there any which using a wrapper for the Key object cannot solve?
Doing it without awkwardness. If the key has important semantics and is
acted on in other ways, having to extract it and wrap it all over the
place gets annoying very quickly and clutters up the code.
Besides, the exact same argument could be made for never introducing
Comparator (and thus for abolishing it now).
Comparator mostly exists because not all classes are
per se Comparable, but all classes are "Equalizable".
There are plenty of cases where also it is useful to have multiple
notions of order-comparison for one type, each such notion used in a
different context. And that right there often implies a different notion
of equality.
So far it looks like WeakHashMap<Key,WeakReference<Value>>
wrapped such as to transparently map the case of a nullified
WeakRef to a "not found" condition.
Maybe you don't want the key to be weak, though? Or don't want the map
to bloat up with dud entry objects. WeakHashMap presumably has some way
of making these go away. It's not easy to see how to implement such a
thing (even subclassing WeakReference and/or ReferenceQueue doesn't open
any new doors) oneself. References must use some VM-hook magic to do
their things, and making map entries that go away when a reference is
cleared likewise seems to require such.
Maybe they even do it with Soft- or WeakRefs.... Actually I wasn't
really sure, that interned Strings really had a chance of being collected.
I think they didn't used to be, in older Java versions.
Hooking into the GC has come up quite frequently here, and most likely
it's a bad idea in the first place.
ReferenceQueue already exists and somewhere there is code that enqueues
references on them. So the "hooking into the GC" at issue here is
already being done. ReferenceQueue doesn't expose any public or
protected methods that can be overridden to do the job, unfortunately,
but whoever can edit its private implementation can surely create such,
ergo Sun can, without changing one byte of the VM or GC implementation.
As it is, I think the effect can be achieved by making a Thread that
calls the blocking poll method on the queue and invokes listener
objects. So my proposal boils down to "put such a thing in the standard
API somewhere for everyone to use it without having to reinvent it".
I don't get that at all. What Subclasses are you now talking about?
Referring to the enum implementation, which has the enum constants
actually singleton instances of same-named subclasses.
Each instance of a given enum can be really one of an anonymous subclass
of the enum, but needs not. In
enum Foo { X, Y, Z}
There is only one class-file: Foo.class. no Foo$X.class, ...
Not on disk, no, but there are four classes in the system at runtime;
some ClassLoader magic sees to that.
There's likewise no MyResourceBundle.class on disk if you have a
PropertiesResourceBundle instead of a ListResourceBundle.
The case I could imagine was a SubEnum, that allowed a free
selection of a subset of BaseEnum's instances, and otherwise
behaves like a wrapper based on my own class-wrapper proposal
(messageid given in my comment to your second item).
Wrap, reduce range, or both. Yep.
* Now finally, I add one more idea to the list:
Distinguish between "using" and "implementing" an interface with
respect to accessibility.
The point being to allow to publish an (internal) interface
for return values (cookies), that foreign code may use as type
for variables, but not in "implements"-lists for classes.
One use would be for a library to return "handle" objects
from some of its methods, and accept these handles as parameters
to other methods, allowing user-code to do well-defined
tasks on these handles outside the library, but preventing
foreign code from implementing own classes for that interface
(and especially: possibly feeding those back to the library)
There are of course other ways to achieve that, like keeping
a WeakHashMap of valid handles, but that's far less elegant.
There's already a few other ways to do this:
public interface Foo {
void method();
}
public final class Bar () {
private static class RealFoo implements Foo {
public void method () { ... }
void otherMethod () { ... }
}
...
aMethod (Foo foo) {
RealFoo r = (RealFoo)foo;
r.otherMethod();
}
}
This one allows subclassing Foo, but throws ClassCastException if a
foreign Foo subclass is used. No WeakHashMap.
Another, even better, one:
public abstract class Foo {
Foo () {
// Package-private constructor.
if (!getClass().equals(RealFoo.class)) {
throw new IllegalStateException();
}
}
public abstract void method ();
}
This won't let anyone even instantiate a BogoFoo. Even using reflection
tricks, or exploiting the wart that you can't make something truly
package-private (invisible even to its own subclasses outside the package).
And then there's:
public final class Foo {
RealFoo delegate; // Package-private field. No subclassing.
public void method () {
delegate.method();
}
}
public final class Bar () {
private static final class RealFoo {
void method () { ... }
void otherMethod () { ... }
}
...
aMethod (Foo foo) {
foo.delegate.otherMethod();
}
}
which appears to cleanly achieve exactly what you want, save that
"delegate" could be molested using reflection (or, perhaps,
serialization hacks).