人一辈子都在高潮——低潮中浮沉,唯有庸碌的人,生活才如死水一般。——傅雷

主要PR:

8338874: [lw5] add nullable types by vicente-romero-oracle · Pull Request #1219 · openjdk/valhalla · GitHub

对应的提交之一如下:

https://github.com/openjdk/valhalla/commit/dbf4f49a57e30e0daa14541adc6a66ea51860182

大概如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
/*
* Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

/*
* @test
* @enablePreview
* @summary Smoke test for parsing of bang types
* @compile NullabilityParsingQuesTest.java
*/

import java.util.function.Consumer;
import java.util.function.Function;

class NullabilityParsingQuesTest {
static value class Point { public implicit Point(); }
static value class Shape { public implicit Shape(); }
// fields
Point? o2;

// method parameters
void m2(Point? o) { }

// method returns
Point? m2() { return new Point(); }

// locals
void testLocals() {
Point? o2;
}

// generics - field
Consumer<Point?> co2;

// generics - method param
void m4(Consumer<Point?> co) { }

// generics - method return
Consumer<Point?> m4() { return null; }

// generics - local
void testGenericLocals() {
Consumer<Point?> co2;
}

// lambdas
void testLambdas() {
Consumer<Point?> co2 = (Point? co) -> {};
}

void testGenericLambdas() {
Consumer<Consumer<Point?>> co2 = (Consumer<Point?> co) -> {};
Consumer<Function<Point?, Point?>> co3 = (Function<Point?, Point?> co) -> {};
Consumer<Consumer<Consumer<Consumer<Point?>>>> co6 = (Consumer<Consumer<Consumer<Point?>>> co) -> {};
}

// type test patterns

void testTypeTestPatterns(Object o) {
switch (o) {
case Point? i -> throw new AssertionError();
case Shape? s -> throw new AssertionError();
default -> throw new AssertionError();
}
}

sealed interface I<X> {}
final class A implements I<Point> { }

void genericTypeTestPatterns(A o) {
switch (o) {
case I<Point?> i -> { }
}
}

sealed interface I2<X> {}
final class A2 implements I2<I<Point>> { }

void genericTypeTestPatterns(A2 o) {
switch (o) {
case I2<I<Point?>> i -> { }
}
}

sealed interface I3<X> {}
final class A3 implements I3<I2<I<Point>>> { }

void genericTypeTestPatterns(A3 o) {
switch (o) {
case I3<I2<I<Point?>>> i -> { }
}
}

// record patterns

record R(A a) { }

void genericRecordPatterns(R o) {
switch (o) {
case R?(I<Point?> i) -> { }
}
}

record R2(A2 a2) { }

void genericRecordPatterns(R2 o) {
switch (o) {
case R2?(I2<I<Point?>> i) -> { }
}
}

record R3(A3 a3) { }

void genericRecordPatterns(R3 o) {
switch (o) {
case R3?(I3<I2<I<Point?>>> i) -> { }
}
}

// instanceof/cast

void testInstanceOf(Object o) {
boolean r2 = o instanceof Point?;
}

void testInstanceRecord(R r) {
boolean r2 = r instanceof R(I<Point?> i);
}

void testCast(Object o) {
Point? s2 = (Point?)o;
}

void testGenericCast(A a) {
I<Point?> i2 = (I<Point?>)a;
}

void testGenericCast2(A a) {
I<Point?> i2 = (I<Point?>)a;
}

// arrays

Point?[]?[]?[]? oarr;
Function<Point?[]?[]?, Function<Point?[]?[]?, Point?[]?[]?>>[][] garr;

void mBad1(Object o) {
Point s1 = o instanceof Point ? (Point)o : null;
Point s2 = o instanceof Point? ? (Point)o : null;
}

void mBad2(Object o) {
Point s1 = o instanceof Point ? null : null;
Point s2 = o instanceof Point? ? null : null;
}

void testPatternRule(Object o) {
switch (o) {
case Point? s -> { }
default -> { }
}
}

void testPatternCol(Object o) {
switch (o) {
case Point? s: { }
default: { }
}
}

void testInstanceOfAndInfix1(Object a, boolean b) {
boolean x2 = a instanceof Point? && b;
}

void testInstanceOfAndInfix2(Object a, boolean b) {
boolean x2 = a instanceof Point? s && b;
}
}