covariant returns for CharBuffer.subSequence
We would like to have return types of methods be the most covariant as is reasonable. The only problem is compatibility. For classes that cannot be subclassed by users, changing covariant returns is almost 100% compatible. (We all know that no change is 100.000000% compatible) The spec for CharBuffer.CharSequence appears to guarantee that the returned object is itself a CharBuffer, so all we need to change is the return type: Hence: diff --git a/src/share/classes/java/nio/ByteBufferAs-X-Buffer.java b/src/share/classes/java/nio/ByteBufferAs-X-Buffer.java --- a/src/share/classes/java/nio/ByteBufferAs-X-Buffer.java +++ b/src/share/classes/java/nio/ByteBufferAs-X-Buffer.java @@ -186,7 +186,7 @@ // --- Methods to support CharSequence --- - public CharSequence subSequence(int start, int end) { + public CharBuffer subSequence(int start, int end) { int pos = position(); int lim = limit(); assert (pos <= lim); diff --git a/src/share/classes/java/nio/Direct-X-Buffer.java b/src/share/classes/java/nio/Direct-X-Buffer.java --- a/src/share/classes/java/nio/Direct-X-Buffer.java +++ b/src/share/classes/java/nio/Direct-X-Buffer.java @@ -391,7 +391,7 @@ // --- Methods to support CharSequence --- - public CharSequence subSequence(int start, int end) { + public CharBuffer subSequence(int start, int end) { int pos = position(); int lim = limit(); assert (pos <= lim); diff --git a/src/share/classes/java/nio/Heap-X-Buffer.java b/src/share/classes/java/nio/Heap-X-Buffer.java --- a/src/share/classes/java/nio/Heap-X-Buffer.java +++ b/src/share/classes/java/nio/Heap-X-Buffer.java @@ -566,7 +566,7 @@ // --- Methods to support CharSequence --- - public CharSequence subSequence(int start, int end) { + public CharBuffer subSequence(int start, int end) { if ((start < 0) || (end > length()) || (start > end)) diff --git a/src/share/classes/java/nio/StringCharBuffer.java b/src/share/classes/java/nio/StringCharBuffer.java --- a/src/share/classes/java/nio/StringCharBuffer.java +++ b/src/share/classes/java/nio/StringCharBuffer.java @@ -99,7 +99,7 @@ return str.toString().substring(start + offset, end + offset); } - public final CharSequence subSequence(int start, int end) { + public final CharBuffer subSequence(int start, int end) { try { int pos = position(); return new StringCharBuffer(str, -1, diff --git a/src/share/classes/java/nio/X-Buffer.java b/src/share/classes/java/nio/X-Buffer.java --- a/src/share/classes/java/nio/X-Buffer.java +++ b/src/share/classes/java/nio/X-Buffer.java @@ -1245,7 +1245,7 @@ * If the preconditions on <tt>start</tt> and <tt>end</tt> * do not hold */ - public abstract CharSequence subSequence(int start, int end); + public abstract CharBuffer subSequence(int start, int end); // --- Methods to support Appendable ---
Martin Buchholz wrote:
We would like to have return types of methods be the most covariant as is reasonable. The only problem is compatibility. For classes that cannot be subclassed by users, changing covariant returns is almost 100% compatible. (We all know that no change is 100.000000% compatible)
The spec for CharBuffer.CharSequence appears to guarantee that the returned object is itself a CharBuffer, so all we need to change is the return type:
Right, buffers are not extensible (no public or protected constructors, etc.) so it does seem safe to take advantage of covariant returns. There are a number of other "opportunities" in this package that Iris and I have chatted about for jdk7. In particular the Buffer flip/etc. methods come up quite often as the more specific return type would facilitate better method invocation chaining. Are you interested in doing those too? I ask because there are a couple of existing RFEs for this (4774077 is the main one)? If not, then we can create a specific bug for subSequence to let you get this done. I see your String updates have a dependency on this. I've only glanced at it so far but I assume by moving the casts you can separate this work if required. -Alan.
Hence:
diff --git a/src/share/classes/java/nio/ByteBufferAs-X-Buffer.java b/src/share/classes/java/nio/ByteBufferAs-X-Buffer.java --- a/src/share/classes/java/nio/ByteBufferAs-X-Buffer.java +++ b/src/share/classes/java/nio/ByteBufferAs-X-Buffer.java @@ -186,7 +186,7 @@
// --- Methods to support CharSequence ---
- public CharSequence subSequence(int start, int end) { + public CharBuffer subSequence(int start, int end) { int pos = position(); int lim = limit(); assert (pos <= lim); diff --git a/src/share/classes/java/nio/Direct-X-Buffer.java b/src/share/classes/java/nio/Direct-X-Buffer.java --- a/src/share/classes/java/nio/Direct-X-Buffer.java +++ b/src/share/classes/java/nio/Direct-X-Buffer.java @@ -391,7 +391,7 @@
// --- Methods to support CharSequence ---
- public CharSequence subSequence(int start, int end) { + public CharBuffer subSequence(int start, int end) { int pos = position(); int lim = limit(); assert (pos <= lim); diff --git a/src/share/classes/java/nio/Heap-X-Buffer.java b/src/share/classes/java/nio/Heap-X-Buffer.java --- a/src/share/classes/java/nio/Heap-X-Buffer.java +++ b/src/share/classes/java/nio/Heap-X-Buffer.java @@ -566,7 +566,7 @@
// --- Methods to support CharSequence ---
- public CharSequence subSequence(int start, int end) { + public CharBuffer subSequence(int start, int end) { if ((start < 0) || (end > length()) || (start > end)) diff --git a/src/share/classes/java/nio/StringCharBuffer.java b/src/share/classes/java/nio/StringCharBuffer.java --- a/src/share/classes/java/nio/StringCharBuffer.java +++ b/src/share/classes/java/nio/StringCharBuffer.java @@ -99,7 +99,7 @@ return str.toString().substring(start + offset, end + offset); }
- public final CharSequence subSequence(int start, int end) { + public final CharBuffer subSequence(int start, int end) { try { int pos = position(); return new StringCharBuffer(str, -1, diff --git a/src/share/classes/java/nio/X-Buffer.java b/src/share/classes/java/nio/X-Buffer.java --- a/src/share/classes/java/nio/X-Buffer.java +++ b/src/share/classes/java/nio/X-Buffer.java @@ -1245,7 +1245,7 @@ * If the preconditions on <tt>start</tt> and <tt>end</tt> * do not hold */ - public abstract CharSequence subSequence(int start, int end); + public abstract CharBuffer subSequence(int start, int end);
// --- Methods to support Appendable ---
On Fri, Aug 1, 2008 at 1:39 AM, Alan Bateman <Alan.Bateman@sun.com> wrote:
Martin Buchholz wrote:
We would like to have return types of methods be the most covariant as is reasonable. The only problem is compatibility. For classes that cannot be subclassed by users, changing covariant returns is almost 100% compatible. (We all know that no change is 100.000000% compatible)
The spec for CharBuffer.CharSequence appears to guarantee that the returned object is itself a CharBuffer, so all we need to change is the return type:
Right, buffers are not extensible (no public or protected constructors, etc.) so it does seem safe to take advantage of covariant returns. There are a number of other "opportunities" in this package that Iris and I have chatted about for jdk7. In particular the Buffer flip/etc. methods come up quite often as the more specific return type would facilitate better method invocation chaining. Are you interested in doing those too? I ask because there are a couple of existing RFEs for this (4774077 is the main one)? If not, then we can create a specific bug for subSequence to let you get this done.
As often happens with me, this change is ever-expanding out of scope. If we have consensus on the covariant returns for other Buffers, I am willing to add these to the change.
I see your String updates have a dependency on this. I've only glanced at it so far but I assume by moving the casts you can separate this work if required.
There is a dependency, but it is for performance only, and it's not actually obvious it's a good idea, since hotspot has gotten so much better at generating the equivalent of the same code on its own. Benchmarking required. Martin
On 08/01/2008 11:04 AM, Martin Buchholz wrote:
As often happens with me, this change is ever-expanding out of scope. If we have consensus on the covariant returns for other Buffers, I am willing to add these to the change.
You've got my vote! Not that it's worth anything. :-) - DML
Martin Buchholz wrote:
: As often happens with me, this change is ever-expanding out of scope. If we have consensus on the covariant returns for other Buffers, I am willing to add these to the change.
I don't mean to twist your arm :-) As this is API change there is a bit of process work which is why I suggested we do it as one bugID rather than several. If you'd prefer I can do the updates to the buffer classes, get the process work started next week, and let you focus on the String updates. -Alan.
Am 01.08.2008 10:39, Alan Bateman schrieb:
In particular the Buffer flip/etc. methods come up quite often as the more specific return type would facilitate better method invocation chaining.
Some time ago I've discussed this with Neal Gafter. My conclusion is, that those problems could be solved by a "this" return type. Example: public abstract class Buffer { public final this flip() { ... return this; } } -Ulf
What about to distinguish chainable from unchainable methods by dropping the 'void' keyword for chainables? So there would be no need to think about a new type, which is not generally usable e.g. for parameters. OK, there would be some chance for confusion with constructors, but method names normally shouldn't start with a capital letter, but constructors should. -Ulf Am 02.08.2008 11:54, Ulf Zibis schrieb:
Am 01.08.2008 10:39, Alan Bateman schrieb:
In particular the Buffer flip/etc. methods come up quite often as the more specific return type would facilitate better method invocation chaining.
Some time ago I've discussed this with Neal Gafter. My conclusion is, that those problems could be solved by a "this" return type.
Example:
public abstract class Buffer {
public final this flip() { ... return this; }
}
-Ulf
On 08/02/2008 04:54 AM, Ulf Zibis wrote:
Am 01.08.2008 10:39, Alan Bateman schrieb:
In particular the Buffer flip/etc. methods come up quite often as the more specific return type would facilitate better method invocation chaining.
Some time ago I've discussed this with Neal Gafter. My conclusion is, that those problems could be solved by a "this" return type.
Or just by using covariant return types, which already exist in the language for this very purpose. Why is everyone so keen to tear up the language, in order to add solutions to problems that already have solutions? - DML
Date: Sat, 02 Aug 2008 09:01:42 -0500 From: david.lloyd@redhat.com
On 08/02/2008 04:54 AM, Ulf Zibis wrote:
Some time ago I've discussed this with Neal Gafter. My conclusion is, that those problems could be solved by a "this" return type.
Or just by using covariant return types, which already exist in the language for this very purpose. Why is everyone so keen to tear up the language, in order to add solutions to problems that already have solutions?
Excellent question! - Mark
On Sat, Aug 2, 2008 at 9:28 PM, Mark Reinhold <mr@sun.com> wrote:
Or just by using covariant return types, which already exist in the
language for this very purpose. Why is everyone so keen to tear up the language, in order to add solutions to problems that already have solutions?
Excellent question!
I think most developers are way too quick to conclude that a language change is needed to solve any particular problem. Most of us can't even begin to understand all the mountainous ramifications and repercussions, nor the incredible effort to safely rev the JLS, etc. That said, I just want to address this idea of "adding solutions to problems that already have solutions." Because among the four language features (two existing and two proposed) - covariant return types - recursive bounds (Foo<A extends Foo<A>>) - 'this' type - void methods implicitly return 'this' No two of these solve exactly the same set of problems as each other. Each addresses at least some situations not addressed by any of the others. So we can't effectively dismiss any of them by simply pointing to the existence of another. And it's fair to have a discussion about what set of problems each of the latter two solves that don't have reasonable solutions already. (But that discussion doesn't belong in this list.) -- Kevin Bourrillion @ Google internal: go/javalibraries google-collections.googlecode.com google-guice.googlecode.com
Am 03.08.2008 06:28, Mark Reinhold schrieb:
On 08/02/2008 04:54 AM, Ulf Zibis wrote:
Some time ago I've discussed this with Neal Gafter. My conclusion is, that those problems could be solved by a "this" return type.
Or just by using covariant return types, which already exist in the language for this very purpose. Why is everyone so keen to tear up the language, in order to add solutions to problems that already have solutions?
Excellent question!
- Mark
Now I have a much better 'conclusion': "Simply implicit method invocation chaining <%3Chttp://mail.openjdk.java.net/pipermail/coin-dev/2009-March/001180.html%3E>" -Ulf
Correction: link was broken. Am 03.08.2008 06:28, Mark Reinhold schrieb:
On 08/02/2008 04:54 AM, Ulf Zibis wrote:
Some time ago I've discussed this with Neal Gafter. My conclusion is, that those problems could be solved by a "this" return type.
Or just by using covariant return types, which already exist in the language for this very purpose. Why is everyone so keen to tear up the language, in order to add solutions to problems that already have solutions?
Excellent question!
- Mark
Now I have a much better 'conclusion': "Simply implicit method invocation chaining <http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/001180.html>" -Ulf
Hi Buffer Buddies, My changes for CharSequence are both easier and less controversial than changes for Buffer.mark,flip,clear. All one has to do in my proposal is change return types. For Buffer methods, on the other hand, one has to copy/paste/modify javadoc from Buffer into its subclasses, and more importantly, remove the "final" modifier on Buffer's methods, which is a noticeable incompatibility, that might perhaps have security or performance implications. So I am declining the invitation to work on those. The covariant CharSequence change can stand on its own. Martin On Fri, Aug 1, 2008 at 1:39 AM, Alan Bateman <Alan.Bateman@sun.com> wrote:
Martin Buchholz wrote:
We would like to have return types of methods be the most covariant as is reasonable. The only problem is compatibility. For classes that cannot be subclassed by users, changing covariant returns is almost 100% compatible. (We all know that no change is 100.000000% compatible)
The spec for CharBuffer.CharSequence appears to guarantee that the returned object is itself a CharBuffer, so all we need to change is the return type:
Right, buffers are not extensible (no public or protected constructors, etc.) so it does seem safe to take advantage of covariant returns. There are a number of other "opportunities" in this package that Iris and I have chatted about for jdk7. In particular the Buffer flip/etc. methods come up quite often as the more specific return type would facilitate better method invocation chaining. Are you interested in doing those too? I ask because there are a couple of existing RFEs for this (4774077 is the main one)? If not, then we can create a specific bug for subSequence to let you get this done.
I see your String updates have a dependency on this. I've only glanced at it so far but I assume by moving the casts you can separate this work if required.
-Alan.
Hence:
diff --git a/src/share/classes/java/nio/ByteBufferAs-X-Buffer.java b/src/share/classes/java/nio/ByteBufferAs-X-Buffer.java --- a/src/share/classes/java/nio/ByteBufferAs-X-Buffer.java +++ b/src/share/classes/java/nio/ByteBufferAs-X-Buffer.java @@ -186,7 +186,7 @@
// --- Methods to support CharSequence ---
- public CharSequence subSequence(int start, int end) { + public CharBuffer subSequence(int start, int end) { int pos = position(); int lim = limit(); assert (pos <= lim); diff --git a/src/share/classes/java/nio/Direct-X-Buffer.java b/src/share/classes/java/nio/Direct-X-Buffer.java --- a/src/share/classes/java/nio/Direct-X-Buffer.java +++ b/src/share/classes/java/nio/Direct-X-Buffer.java @@ -391,7 +391,7 @@
// --- Methods to support CharSequence ---
- public CharSequence subSequence(int start, int end) { + public CharBuffer subSequence(int start, int end) { int pos = position(); int lim = limit(); assert (pos <= lim); diff --git a/src/share/classes/java/nio/Heap-X-Buffer.java b/src/share/classes/java/nio/Heap-X-Buffer.java --- a/src/share/classes/java/nio/Heap-X-Buffer.java +++ b/src/share/classes/java/nio/Heap-X-Buffer.java @@ -566,7 +566,7 @@
// --- Methods to support CharSequence ---
- public CharSequence subSequence(int start, int end) { + public CharBuffer subSequence(int start, int end) { if ((start < 0) || (end > length()) || (start > end)) diff --git a/src/share/classes/java/nio/StringCharBuffer.java b/src/share/classes/java/nio/StringCharBuffer.java --- a/src/share/classes/java/nio/StringCharBuffer.java +++ b/src/share/classes/java/nio/StringCharBuffer.java @@ -99,7 +99,7 @@ return str.toString().substring(start + offset, end + offset); }
- public final CharSequence subSequence(int start, int end) { + public final CharBuffer subSequence(int start, int end) { try { int pos = position(); return new StringCharBuffer(str, -1, diff --git a/src/share/classes/java/nio/X-Buffer.java b/src/share/classes/java/nio/X-Buffer.java --- a/src/share/classes/java/nio/X-Buffer.java +++ b/src/share/classes/java/nio/X-Buffer.java @@ -1245,7 +1245,7 @@ * If the preconditions on <tt>start</tt> and <tt>end</tt> * do not hold */ - public abstract CharSequence subSequence(int start, int end); + public abstract CharBuffer subSequence(int start, int end);
// --- Methods to support Appendable ---
Martin Buchholz wrote:
Hi Buffer Buddies,
My changes for CharSequence are both easier and less controversial than changes for Buffer.mark,flip,clear. All one has to do in my proposal is change return types.
For Buffer methods, on the other hand, one has to copy/paste/modify javadoc from Buffer into its subclasses, and more importantly, remove the "final" modifier on Buffer's methods, which is a noticeable incompatibility, that might perhaps have security or performance implications. So I am declining the invitation to work on those. The covariant CharSequence change can stand on its own.
Okay. I've created the following to track this: 6733145: (bf) CharBuffer.subSequence can be updated to take advantage of covariant returns -Alan.
participants (6)
-
Alan Bateman
-
David M. Lloyd
-
kevin bourrillion
-
Mark Reinhold
-
Martin Buchholz
-
Ulf Zibis