You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The Java Plugin to use string interpolation for Java (like in Kotlin).
10
10
Supports Java 8, 9, 10, 11, ...
11
11
12
-
13
12
## Motivation
14
13
15
-
In the latest JEPs https://openjdk.java.net/jeps/355, we have the only expectation of the RAW string literals,
16
-
but there is nothing about the string interpolation.
14
+
In the latest JEPs https://openjdk.java.net/jeps/355, we have the only expectation of the RAW string literals, but there is nothing about the string interpolation.
17
15
18
16
And it’s so sad, that we need writing code like this in the 2020 year:
19
17
20
-
[source,java]
18
+
[source,java]
21
19
----
22
20
int a = 3;
23
21
int b = 4;
@@ -29,7 +27,7 @@ just to print the string: `3 + 4 = 7`
29
27
30
28
of course, we can use a `var` since Java 10:
31
29
32
-
[source,java]
30
+
[source,java]
33
31
----
34
32
var a = 3;
35
33
var b = 4;
@@ -42,7 +40,7 @@ But this code is still sad =(
42
40
43
41
### Using variables in string literals
44
42
45
-
[source,java]
43
+
[source,java]
46
44
----
47
45
var a = 3;
48
46
var b = 4;
@@ -53,24 +51,26 @@ prints: `3 + 4 = 7`
53
51
54
52
### Using expressions
55
53
56
-
[source,java]
54
+
[source,java]
57
55
----
58
56
var a = 3;
59
57
var b = 4;
60
58
System.out.println("flag = ${a > b ? true : false}");
61
59
----
60
+
62
61
prints: `flag = false`
63
62
64
-
[source,java]
63
+
[source,java]
65
64
----
66
65
var a = 3;
67
66
System.out.println("pow = ${a * a}");
68
67
----
68
+
69
69
prints: `pow = 9`
70
70
71
71
### Using functions
72
72
73
-
[source,java]
73
+
[source,java]
74
74
----
75
75
@Test
76
76
void functionCall() {
@@ -85,21 +85,83 @@ long factorial(int n) {
85
85
return fact;
86
86
}
87
87
----
88
+
88
89
prints: `fact(5) = 120`
89
90
91
+
### Using string interpolation in class fields
92
+
93
+
you can use better-string for string interpolation in class fields, for example:
94
+
95
+
[source,java]
96
+
----
97
+
public class Test {
98
+
public String field = "${3+4}";
99
+
public String getField(){
100
+
return "field = ${field}";
101
+
}
102
+
}
103
+
----
104
+
105
+
`new Test().getField()` prints : `field = 7`
106
+
107
+
### Using string interpolation in default methods of interfaces
108
+
109
+
also you can use string interpolation with default methods in interfaces like this:
110
+
111
+
[source,java]
112
+
----
113
+
public interface InterfaceWithDefaultMethod {
114
+
default String sum(){
115
+
return "sum = ${1+2}";
116
+
}
117
+
}
118
+
119
+
public class Test implements InterfaceWithDefaultMethod {
120
+
public String test() {
121
+
return sum();
122
+
}
123
+
}
124
+
----
125
+
126
+
The result of `new Test().test()` is `sum = 3`
127
+
128
+
### Using string interpolation in enums
129
+
130
+
In addition you can use string interpolation for code of enums:
`EnumCode.THIRD.toString();` should print: `value: THIRD, order: 3`
147
+
148
+
### Limitations
149
+
150
+
It's impossible to use the string interpolation within annotations value.
151
+
It provides compatibility with spring framework properties injecting by the `@Value` annotation.
152
+
90
153
91
154
### Disclaimer
92
155
93
156
NOTE: Keep in mind that this feature should be used carefully.
94
-
You shouldn't write too much code inside string literals
95
-
because it is too difficult to maintain and maybe not obvious for debugging.
157
+
You shouldn't write too much code inside string literals because it is too difficult to maintain and maybe not obvious for debugging.
96
158
97
159
98
160
## Getting started
99
161
100
162
You need to add the following dependency:
101
163
102
-
[source,xml]
164
+
[source,xml]
103
165
----
104
166
<dependency>
105
167
<groupId>com.antkorwin</groupId>
@@ -114,7 +176,7 @@ And you can use string interpolation anywhere in your code.
114
176
115
177
To skip the string interpolation for class, method or field you can use the `@DisabledStringInterpolation` annotation:
116
178
117
-
[source,java]
179
+
[source,java]
118
180
----
119
181
@DisabledStringInterpolation
120
182
class Foo {
@@ -126,66 +188,58 @@ class Foo {
126
188
127
189
this code prints: `${a+b}`
128
190
129
-
Also, you can use the following workaround
130
-
to escape string interpolation locally in your code:
191
+
Also, you can use the following workaround to escape string interpolation locally in your code:
131
192
132
-
[source,java]
193
+
[source,java]
133
194
----
134
195
System.out.println("${'$'}{a+b}");
135
196
----
136
197
137
198
the result is : `${a+b}`
138
199
139
-
140
200
## How to control the generated code
141
201
142
-
Better Strings is a Java Annotation Processor,
143
-
but it does not process specific annotations, it makes AST modification of your code while javac compiling it.
202
+
Better Strings is a Java Annotation Processor, but it does not process specific annotations, it makes AST modification of your code while javac compiling it.
144
203
145
204
By default, each `${...}` occurrence translates into an invocation of `String#valueOf`.
146
205
For instance, a string:
147
206
148
-
[source,java]
207
+
[source,java]
149
208
----
150
209
"Result: ${obj}.method() = ${obj.method()}"
151
210
----
152
211
153
212
will yield:
154
213
155
-
[source,java]
214
+
[source,java]
156
215
----
157
216
"Result: "
158
217
+ String.valueOf(obj)
159
218
+ ".method() = "
160
219
+ String.valueOf(obj.method())
161
220
----
162
221
163
-
Under certain circumstances (e.g. with certain static code analyzers), however,
164
-
it might be preferred that the generated code contains an explicit `toString` invocation for each `${...}` occurrence containing a non-null value.
222
+
Under certain circumstances (e.g. with certain static code analyzers), however, it might be preferred that the generated code contains an explicit `toString` invocation for each `${...}` occurrence containing a non-null value.
165
223
This can be controlled with `-AcallToStringExplicitlyInInterpolations` compiler option, which will instead make the above string translate into:
NOTE: this causes the inner part of each `${...}` to be evaluated twice,
176
-
which might be problematic if the expression is side-effecting, non-deterministic or expensive to compute.
177
-
233
+
NOTE: this causes the inner part of each `${...}` to be evaluated twice, which might be problematic if the expression is side-effecting, non-deterministic or expensive to compute.
178
234
179
235
## How to use with other annotation processors
180
236
181
-
If you need to use multiple annotation processors (for example `better-strings` with `lombok` or `mapstruct`)
182
-
and the order of processing is necessary for you then you can set the order in your building tool.
237
+
If you need to use multiple annotation processors (for example `better-strings` with `lombok` or `mapstruct`) and the order of processing is necessary for you then you can set the order in your building tool.
183
238
184
-
In maven, you should declare dependencies as usually,
185
-
then describe annotation processors in the configuration of the `maven-compiler-plugin`
239
+
In maven, you should declare dependencies as usually, then describe annotation processors in the configuration of the `maven-compiler-plugin`
0 commit comments