The rule is the tail; the dog is that "sealing is tight coupling, so
sealed hierarchies should be co-maintained." We don't have formal
maintenance boundaries, but packages (for non-modular code) and modules
(for modular code) are the closest approximation. Bristling at the rule
is really bris
When working with modules, it is a fairly common practice to structure
applications are libraries in multiple set of packages - a package
containing the publicly exported types by a given module, and another
package containing the "implementation types". I find this way of
splitting much mo
Bootstrap methods are cheap. If you have one that is semantically
different, better to write a separate bootstrap than to try and cram two
sets of functionality into one. So +1 for "make a new bootstrap for enums."
On 6/16/2021 11:25 AM, Jan Lahoda wrote:
Currently, an enum switch with patter
On 6/7/2021 11:13 AM, Dan Smith wrote:
On Jun 5, 2021, at 9:21 AM, Brian Goetz wrote:
Rampdown is next week; time is fleeting.
I think the path of adding Objects::newIdentity in 17 seems the best
alternative. If there are objections, make them now.
I still think that's a second
On 6/7/2021 5:51 AM, Remi Forax wrote:
Hi all,
the first part of the message is about javac error message that could be
improved,
the second part is about the current spec being not very logical.
With this code
Object o = null;
var value = switch(o) {
//case null -> 0;
On 6/7/2021 5:51 AM, Remi Forax wrote:
Hi all,
the first part of the message is about javac error message that could be
improved,
the second part is about the current spec being not very logical.
With this code
Object o = null;
var value = switch(o) {
//case null -> 0;
Rampdown is next week; time is fleeting.
I think the path of adding Objects::newIdentity in 17 seems the best
alternative. If there are objections, make them now.
On 6/4/2021 4:10 PM, Dan Heidinga wrote:
Quoting from several previous emails in this thread:
Brian said:
I agree that we can i
After a few minutes of thought, I think it might be a better fit to put this at
Objects::newIdentity. The methods in Objects are conveniences that users could
write themselves, which this basically is -- there's nothing special about this
method, other than having a preferred alternative t
It seems pretty clear that this "feature" is a leftover from an early
implementation, doesn't clearly say what it is supposed to do, is more
complicated than it looks, and is buggily implemented. While I
understand the temptation to "fix" it, at this point we'd realistically
be adding a basica
to `new Object()` which users will understand. So parking
this where the Object conveniences go seems slightly lower friction.
On 6/2/2021 10:50 AM, Dan Smith wrote:
On May 8, 2021, at 1:20 PM, Brian Goetz wrote:
I agree that we can introduce the new API point immediately. The 17 window
The motivation here is that we wanted to preserve the ability to
describe "special" indy sites with special objects. The standard
implementation can describe any indy site (bootstrap, static args,
invocation name and type), but some indy sites (e.g., lambda capture)
are "special". It would be
Since the discussion happened over the holiday weekend, I didn't get a
chance to respond until now, but I think that this came to a good
outcome. As Alan's archaeology discovered, this flag appears to be a
leftover from the original implementation, and I could find no signs of
its usage. We m
On Tue, 25 May 2021 11:49:18 GMT, Tagir F. Valeev wrote:
>> Inspired by PR#4088. Most of the changes are done automatically using
>> IntelliJ IDEA refactoring. Some manual adjustments are also performed,
>> including indentations, moving comments, extracting common cast out of
>> switch expres
On Tue, 25 May 2021 11:49:18 GMT, Tagir F. Valeev wrote:
>> Inspired by PR#4088. Most of the changes are done automatically using
>> IntelliJ IDEA refactoring. Some manual adjustments are also performed,
>> including indentations, moving comments, extracting common cast out of
>> switch expres
On Tue, 25 May 2021 11:49:18 GMT, Tagir F. Valeev wrote:
>> Inspired by PR#4088. Most of the changes are done automatically using
>> IntelliJ IDEA refactoring. Some manual adjustments are also performed,
>> including indentations, moving comments, extracting common cast out of
>> switch expres
On Tue, 25 May 2021 11:49:18 GMT, Tagir F. Valeev wrote:
>> Inspired by PR#4088. Most of the changes are done automatically using
>> IntelliJ IDEA refactoring. Some manual adjustments are also performed,
>> including indentations, moving comments, extracting common cast out of
>> switch expres
On Tue, 25 May 2021 11:49:18 GMT, Tagir F. Valeev wrote:
>> Inspired by PR#4088. Most of the changes are done automatically using
>> IntelliJ IDEA refactoring. Some manual adjustments are also performed,
>> including indentations, moving comments, extracting common cast out of
>> switch expres
On Tue, 25 May 2021 11:49:18 GMT, Tagir F. Valeev wrote:
>> Inspired by PR#4088. Most of the changes are done automatically using
>> IntelliJ IDEA refactoring. Some manual adjustments are also performed,
>> including indentations, moving comments, extracting common cast out of
>> switch expres
In the last hunk, you convert
case Collator.IDENTICAL: toAddTo.append('='); break;
case Collator.TERTIARY: toAddTo.append(','); break;
case Collator.SECONDARY: toAddTo.append(';'); break;
case Collator.PRIMARY: toAddTo.append('<'); break;
case RESET: toAd
rstood Brian, great answer.
>
> Could you please answer to my other proposal?:
> https://mail.openjdk.java.net/pipermail/core-libs-dev/2021-May/077955.html
>
> Regards,
>
> Alberto.
> ________
> De: Brian Goetz
> Enviado: sábado, 22 de mayo de
There is no end to patterns of code that could be generated by tools, and for
each of them, one can imagine situations where they would be useful. But in
addition to the other reply about how builders are really only called for when
there are a large number of _optional_ components, the premise
Has it ever been conceived to create an entire new API like how it was
done for Dates and Times? Obviously this would be a massive
undertaking, but it seems to me we've just about reached the limits of
how far we can stretch the current API.
"This code is a mess, we should throw it away and r
K: yield X; // expression switch, X is an expression
case L, J, K: X; // expression switch, X is a block
case L, J, K: X; break; // statement switch
and
case L, J, K: X;
is-shorthand-for
case L:
case J:
case K:
X;
On 5/17/2021 5:36 PM, Brian Goetz wr
- tuple as first class citizen
Sorry, no. I know you really want this, but this is similar to the
function-type-vs-functional-interface issue. We made our choice when we
did records -- records are our tuples.
I'm hunting around deconstructor and methods that returns several values.
I k
to fill the gap, we need
- _ as pattern equivalent to var _ + _ not be entered in the scope
On the list, will come at some point.
- constant as pattern, Foo(constant) being equivalent to Foo(var x) && x ==
constant
Maybe, not sure it carries its weight.
- inference of Type in a d
There are a few roads not taken: “switch ()” with boolean
case expressions has not showed itself worthy yet.
Yep, this one can sit on the shelf.
I’d also like to point out “switch (a, b)” as a possible area
of future work for switch, where the thing after “switch” is a
more generalized arg
I think we've done a remarkable job at rehabilitating this monster.
I believe the only pending issue on that matter is the position of
default inside the switch,
With the legacy switch, default can be in the middle, with a switch on
types that default has to be the last case.
I think
This is a good time to look at the progress we've made with switch.
When we started looking at extending switch to support pattern matching
(four years ago!) we identified a lot of challenges deriving from
switch's C legacy, some of which is summarized here:
http://cr.openjdk.java.net/~briang
Let's try again: why is that important? What decisions would you
make differently if you had this information? What benefit would
come from those decisions?
Threading is hard.
Gee, thanks MIke for pointing that out to me, obviously I'm new to the
topic :)
Scoped variables a
Let's back up a lot of steps; you're deep in proposing a solution
when you've not even explained what problem you think you're
solving. So control question, which I hope will start to expose
the assumptions:
Why do you think its important to know that a snapshot of a
How so? How do I know if a snapshot of my variable has occurred?
Let's back up a lot of steps; you're deep in proposing a solution when
you've not even explained what problem you think you're solving. So
control question, which I hope will start to expose the assumptions:
Why do you t
The lifecycle is bounded by the duration of the Runnable passed to the
`run()` method.
In the simple case, with no inheritance and no snapshotting:
ScopedLocal.where(x, xExpr).run(r)
the lifecycle of the binding starts when we enter r, and ends when we
return from r.
With snapshotting,
Its simpler than you're making it. Think of the motivating use cases
for ThreadLocal, such as when a container calls into user code, and the
user code calls back into the container, and we need to keep track of
{transaction, security, etc} context, and it is impractical to pass them
all throug
ning a slash is
still valid (I haven't found any of such test though).
Mandy
On 5/11/21 6:20 AM, Brian Goetz wrote:
There may be some JDK code that checks for anon classes by comparing the name
to see if it contains a slash, especially tests, but which don’t say
“anonymous”. Did you d
ning a slash is
still valid (I haven't found any of such test though).
Mandy
On 5/11/21 6:20 AM, Brian Goetz wrote:
There may be some JDK code that checks for anon classes by comparing the name
to see if it contains a slash, especially tests, but which don’t say
“anonymous”. Did you d
Scope locals have come together nicely.
I have some vague thoughts on the presentation of the JEP draft. There
are (at least) three intertwined things in the motivation:
- ThreadLocal (and ITL especially) were always compromises, and with
the advent of Loom, have become untenable -- but the
Yes, please!
To add to the list of motivations/things to remove: the current
implementation relies on the special `MagicAccessorImpl` to relax
accessibility. The notes in this class are frightening; getting rid of
it would be a mercy.
On 5/11/2021 4:42 PM, Mandy Chung wrote:
This draft JE
There may be some JDK code that checks for anon classes by comparing the name
to see if it contains a slash, especially tests, but which don’t say
“anonymous”. Did you do a search for these idioms too, which are now dead
tests?
Sent from my iPad
> On May 11, 2021, at 8:59 AM, Harold Seigel w
There may be some JDK code that checks for anon classes by comparing the name
to see if it contains a slash, especially tests, but which don’t say
“anonymous”. Did you do a search for these idioms too, which are now dead
tests?
Sent from my iPad
> On May 11, 2021, at 8:59 AM, Harold Seigel w
Yes, this has been considered at some length. The summary verdict is:
- Method references for static/unbound methods seem like reasonable
constant literals to put in annotations, not unlike class literals.
- Lambdas, on the other hand: absolutely, positively, not.
To actually get to method
The logical conclusion is that java.lang.Object is a parametric class with a
parameter saying if it should implement IdentityObject or not.
Magic hammer, meet nail :)
To be explicit, what you're suggesting is something like
class Object { ... }
where an identity class extends Object
I agree that we can introduce the new API point immediately. The 17
window hasn't even closed yet! But we'd have to get a move on. But
realistically, we can expect it to be several years before we are
comfortable erroring on the `new Object()` constructor.
One way or another, we've got a
We're in complete agreement on needing to support it at the bytecode
level. The part I'm unclear on is why that requires continuing to
allow `new Object()` at the source level. Removing it is, of course,
a source incompatible change with all its attendant pain, but it
results in the simpler
From a compatibility perspective, we can't outlaw either `new Object()`
or `new j/l/Object`, but we can (a) add Object::newInstance and (b) warn
on recompilation to switch to `Object::newInstance`.
On 5/7/2021 9:06 PM, Dan Heidinga wrote:
I would strongly discourage new developers from saying
I think the question is: "cleaner for whom." The parenthetical remarks
"except for Object" are mostly our mess to corral; "new Object()"
working, even when Object is seen to be abstract, will be extremely
confusing for new developers learning what abstract means. It's not
just that reflection
Here are some idioms I can imagine a use for with IdentityObject:
// parameter type
void withLock(IdentityObject monitor, Runnable task)
// type bound
Map map = ... // gonna lock on keys
// dynamic check
if (x instanceof IdentityObject) {
sync (x) { task(); }
2. Whether abstract classes are primitive superclass candidates. The static
compiler will check this at compilation time when it sees a superclass of a
primitive class, but the JVM will want to recheck anyway. There are two
sensible ways to handle this in the classfile:
- An attribute
While I agree that we should be careful, let's not paint ourselves into
an either/or strawman. The choice is not "never add anything to
Collection" vs "let's dump every silly idea that comes to anyone's mind
into Collection"; it is, as always, going to involve tradeoffs between
stability and e
inder, but it would
get large and esoteric quickly if pattern nesting got "deep" or "wide".
Seems mostly like an ugly secret the compiler should keep to itself.
On 4/29/2021 10:48 AM, Maurizio Cimadamore wrote:
On 29/04/2021 15:46, Brian Goetz wrote:
I don't think w
Without diving into the translation details prematurely, I just want to
note that we *do* want the compiler to "totalize" things for us,
because, DA. Suppose we have A permits B, C:
int x ;
switch (a) {
case B(int foo): x = foo; break;
case C(int bar): x = bar; break;
Whenever you have a deconstruction pattern, there's always a remainder
null. (Point(var x, var y) NPEs on null.)
Whenever you cover a sealed type with alternatives (but no total
pattern), there's always remainder null and "novel".
Whenever you lift over a nestable pattern (like D(T), or Strin
On 4/28/2021 5:34 PM, Maurizio Cimadamore wrote:
Thanks for this.
It is especially helpful to see all the rules in a single place.
So, armed with these rules - back to the first example I brought up:
switch (lunch) {
case Box(Soup s) {
if (s == null) {
I've updated this document to subsume the translation details from
source to classfile. With the new single-file translation, this part,
which used to be its own whole document, is now a small-ish (and mostly
obvious) section at the end of the VM Model document.
On 4/21/2021 2:51 AM, John Ros
I'm updating the SoV documents and it raises a few questions about what
classfile surface we need for capturing the language model. The good
news is that with the single-classfile model, the translation complexity
collapses almost to zero. But there are a few questions of "what do we
retain i
being total (or exhaustive) on T
This sent me completely haywire, because I was trying to reason in
terms of what a plain pattern instanceof would consider "total", and
then translate the results to nested patterns in switch - and that
didn't work, because two different sets o
t me completely haywire, because I was trying to reason in
terms of what a plain pattern instanceof would consider "total", and
then translate the results to nested patterns in switch - and that
didn't work, because two different sets of rules apply there.
Maurizio
On 28/04/2021
The benefit is twofold: not only does the user not have to write the
stupid cases (imagine if Box had ten slots, would we want to write the
2^10 partial null cases?), but because we throw on the remainder, DA
can treat the switch as covering all boxes, and be assured there are
no leaks.
Mor
I think part of the problem is that we're using the word "total" in
different ways.
A pattern P may be total on type T with remainder R. For example, the
pattern `Soup s` is total on `Soup` with no remainder.
A _set_ of patterns may be total on T with remainder R as well. (The
only way a se
us
also { null } because of the lifting.
On 4/28/2021 12:33 PM, Maurizio Cimadamore wrote:
On 28/04/2021 17:29, Brian Goetz wrote:
I assume that you are saying Box permits Soup only. But your
assumptions about "where do the nulls go" here are not right.
Box(Soup) does not ma
Let's say I start with this:
switch (lunch) {
case Box(Soup s) {
if (s == null) {
System.err.println("Box of null");
} else {
System.err.println("Box of soup");
}
}
case Bag(Soup s): {
I guess the case I'm referring to is:
switch (lunch) {
case Box(Soup s):
case Bag(Soup s):
}
Where Soup is the only know subtype of Lunch. This code is exhaustive,
but is Sandwich is added, it is no longer so.
Given Lunch is sealed to only permit Soup, and Container = Box|
At least, if you want a total type, you can make it explicit using
case var x
which is always total whatever the type switched upon.
So you have two tools to avoid influence at distance in the totality
analysis,
- for a switch where you can enumerate all the values enums, sealed
type (bool
- for a switch where you can enumerate all the values enums, sealed
type (boolean should be in that category too IMO, but we did not agree
on that), if you list all the possible cases, a total case is not
required.
In fact, when you can enumerate the values/types, it is better to _not_
hav
This will not solve the problem of Maurizio for sub-patterns but i
like it.
I agree it doesn't *solve* the problem, but it helps somewhat.
We don't have to later transform the warning to an error, keeping it
as a warning can be annoying enough to force people to change their
code (or ALT-
Maurizio's comment got me thinking about a possible way to eliminate the
sharp edge of "sometimes switches are type-checked for exhaustiveness,
and sometimes not."
Historically, there is no requirement that switches be exhaustive;
legacy switches without a default are like unbalanced ifs. (No
You've put your finger on the fundamental stewardship challenge here.
If we were never going to go any farther than "deconstruction patterns
in switch", then we would surely do a "worse is better" hack which
separates nullity from totality. But, if we want deconstruction
patterns (or Optional
I also lightly updated the 01- and 02- documents based on recent
discussions.
On 4/21/2021 2:51 AM, John Rose wrote:
Brian and I hammered out a document this week that
captures what we think is emerging as our shared
understanding of how adapt the JVM to support
primitive classes.
It is still
This is basically Spliterator, an iterator + a size, with the iterator is "push" instead
of "pull" because it's more efficient.
In details a Spliterator is either
- an Iterable (with no SIZED characteristic)
- an Iterable + size (if SIZED and estimateSize() != Long.MAX_VALUE)
- an Iterable +
Is there a compelling example of where this would be used by clients?
Here are some examples:
https://stackoverflow.com/questions/10988634/java-global-isempty-method
Without passing judgment on the sort of dynamically typed programs that
need a method like this, or wondering what monstrositie
On 4/23/2021 4:25 PM, Remi Forax wrote:
Bottom line: Trust the users to choose how
explicit to be with nulls. More importantly,
trust them with compositional notations.
That's a solution, we do nothing and trust users.
The other solution is to force users to explicit say that the pattern is
Now, let's look back at the alternative, where we keep the flexibility of the
null label, but treat patterns as meaning what they mean, and letting switch
decide to throw based on whether there is a nullable pattern or not. So a
switch with a total type pattern -- that is, `var x` or `Objec
Very nice how the restrictions on primitive narrowing shook out.
In 8.1.1.2, you mention that JEP 395 proposes records, but records are
now a permanent feature.
On 4/20/2021 5:00 AM, Gavin Bierman wrote:
Dear experts:
Draft of the specs for JEP 409 (Sealed Types) are available at:
http://c
This has come up before. For example, during an early iteration of the
Stream design, before parallelism entered the picture. The first
scrawled-on-a-napkin prototype for streams was based on Iterator, and it
took about a minute to realize that we could do a much better job if we
had a slight
- A switch accepts null if (a) one of the case labels is `null` or (b)
the switch has a total pattern (which must always be the last case.)
On 3/12/2021 9:12 AM, Brian Goetz wrote:
The JEP has some examples of how the `null` case label can combine
with others. But I would like to propos
Adding a REVERSIBLE characteristic to spliterators is easy enough, and
as you say, many useful sources can easily provide an efficient reverse
operation. Filtering and mapping can preserve reversibility. The real
question is what to do if someone calls reverse() on a non-reversible
stream. (F
Project Valhalla will allow Instant to be migrated to a primitive class,
which would address your problem.
On 4/2/2021 7:47 PM, Ralph Goers wrote:
Log4j 2 supports the notion of a PreciseClock - one that can be initialized to
something more precise than a millisecond. At the same time it also
By example, a type WithCheese may make little sense.
Anyway, if WithCheese only makes sense for a Sandwich, nesting
WithCheese inside Sandwich is the way to go.
This doesn't help unless the *whole* hierarchy is nested in the same
file. Otherwise you have to have an explicit permits clause
Essentially, I want to put the `permits` list on Sandwich, and
have `WithCheese` and friends delegate their permits to
`Sandwich`, rather than having each interface enumerate their
subtypes.
I'm not sure to understand why this case is special enough to get a
special way of de
o the copy/paste at classload. Both
are possible but the VM option is more expensive to implement.
--Dan
On Thu, Apr 1, 2021 at 9:24 AM Brian Goetz wrote:
Been working with sealed classes a lot lately, and have run into a pattern that
we might want to consider supporting more directly, which is
Been working with sealed classes a lot lately, and have run into a
pattern that we might want to consider supporting more directly, which
is interfaces that exist solely to refine a sealed class or interface.
Suppose we have:
sealed abstract class Sandwich { }
interface WithCheese { }
They'll find a natural home in JDBC, since SQL has a native decimal type.
On 3/30/2021 7:05 PM, Raffaello Giulietti wrote:
As far as I can tell, scientific computation will make use of binary
floating point numbers for a long time. Decimal floating point numbers
are still limited to biz and f
Overall, I'd be happy to see Decimal types that are aimed at "reasonable
precision" in addition to the infinite precision that BD offers. (After
Valhalla, of course.)
On 3/29/2021 4:14 PM, Raffaello Giulietti wrote:
Hello,
I'm experimenting with an implementation of Decimal64 and Decimal12
I think it's missing a discussion about lambdas, anonymous classes and
local classes that can all extends/implements a sealed type.
For Lambdas and anonymous classes, it's easy, they are anonymous, so
have no name to list in the permits clause.
Yes, we should state these exclusions explicit
Pattern assignment should work in all of the following contexts:
- Assignment statements: P = e
- foreach-loops: for (P : e) { ... }
- (optional) try-with-resources: try (P = e) { ... }
- (optional) method formals: void m(Point(var x, var y) p) { ... }
- (optional) lambda formals: (Point(
goal here
would be to provide _safety_ for primitive types for which the default
is dangerous.
On 3/15/2021 11:52 AM, Brian Goetz wrote:
Picking this issue up again. To summarize Dan's buckets:
Bucket 1 -- the zero default is in the domain, and is a sensible
default value. Zero
Picking this issue up again. To summarize Dan's buckets:
Bucket 1 -- the zero default is in the domain, and is a sensible default
value. Zero for numerics, empty optionals.
Bucket 2 -- there is a sensible default value, but all-zero-bits isn't it.
Bucket 3 -- there simply is no sensible defa
It's definitely a mistake that we do nothing here.
There are two options. The obvious is to simply raise a raw warning;
this is a straightforward spec/impl fix which we can easily do.
The other option is to do as we did with method refs, where we apply
type inference to an unadorned `Foo` pa
What I mean is that if I have a method
void m(Integer x) { }
and I call m(1), then today we do an boxing conversion because
boxing is one of the conversions we do in method invocation
context. If we want to interpret this as a pattern match, we
should get the same
texts.
Suppose that I write:
try (Foo(Bar x)) {
...
}
What should be closed in the finally? The variable x that we bound to,
or the Foo that contained it? Both answers seem a little weird to me.
Might it be better not to allow patterns in this context?
On Fri, Mar 12, 2021 at 12:41 PM Brian
Minimally, we have to align the semantics of local variable
declaration with assignment with that of pattern matching; `T t =
e` should have the same semantics whether we view it as a local
declaration plus assignment, or a pattern match. This means that
we have to, minimally
While this is not on the immediate horizon, I think we are ready to put
the pieces together for pattern assignment. I think we now understand
the form this has to take, and the constraints around it.
Just as we were successfully able to unify pattern variables with
locals*, I would like to be
The JEP has some examples of how the `null` case label can combine with
others. But I would like to propose a more general way to describe
what's going on. This doesn't change the proposed language (much), as
much as describing/specifying it in a more general way.
We have the following kinds
In the section "Dominance of pattern label",
It's not clear to me if there is a dominance in between expressions,
by example, can we have the following cases in that order ?
case Foo(var a, var b) && a == 3:
case Foo(var a, var b) && a == 3 && b == 4:
for me the answer is yes, the domi
You nail the guard to a pattern, which is equivalent until we have
nested patterns (and "or"/"and" patterns).
We have nested patterns already in the JEPs on the table. Where's the
problem?
I see a lot of advantages of using && to link a guard to a pattern,
- the symbol is heavy so there
Using & between patterns is unfortunate given that if if first pattern is not total and
does not match, we will not "execute" the second pattern.
So the semantics is lazy but currently '&' means non-lazy on expressions.
While I understand the discomfort that drives you to make this
observat
This feels like we landed in a good place. It preserves the underlying
goal of the original approach -- that we can compose patterns with
patterns, and patterns with boolean expressions, and doesn't require
nailing bags onto switch (yay). The main difference is that it creates
a distinguished
These patches are obviously minimally correct. However, for equals
methods at least, I would take them one step further, from:
if (!(o instanceof Key that)) return false;
//noinspection StringEquality (guaranteed interned String(s))
return name == that.name &
There are two kinds of input args, one is the implicit target, the others are
other arguments.
It's not obvious to me that the parameters other than the target have to have
access to the bindings.
You keep saying "access to the bindings" as if that is a special thing.
Bindings are ordinar
Apart from what have said about letting grobble to fully access to the
bindings
Except that argument doesn't make sense. Accessing the bindings is not
a special behavior of grobble, but a natural consequence of flow
scoping. If I have P && g (or P & grobble(g)), then the scoping rules
wi
Looks good! Glad to see the Amber features finding their way into the
codebase.
On 3/8/2021 1:53 PM, Patrick Concannon wrote:
Hi,
Could someone please review my code for updating the code in the `java.io`,
`java.math`, and `java.text` packages to make use of the `instanceof` pattern
variabl
601 - 700 of 2342 matches
Mail list logo