Before anyone screams about EOL'ed JDK, I'd like to point out that my question is not about how to compile the following. There is a real question here and it's not about JDK 1.5 being EOL'ed...
The following under JDK 1.5, up to 1.5.0_22 (the last one I could find) produces on my system a compiler error:
private Object[] boozinga() {
boolean b = Math.abs(42) > 0;
Object[] res = new Object[1];
res[0] = b ? new int[1] : new String[1];
return res;
}
Changing the Math.abs(42) > 0 to true allows compilation.
Changing the ternary "assignment" to an if/else allows compilation.
Using JDK 1.6 allows compilation.
So I was wondering: is there something not legal in the above code under Java 1.5 and that is allowed under Java 1.6?
Does it crash for those of you that are under Java 1.5 too?
The crash says something like this:
An exception has occured in the
compiler (1.5.0_22). Please file a bug
at the Java Developer Connection
(http://java.sun.com/webapps/bugreport)
after checking the Bug Parade for
duplicates. Include your program and
the following diagnostic in your
report. Thank you.
I take it filling a bug report for an EOL'ed JDK is an exercice in futility but still, I'd still like to know if the above is valid Java 1.5 code or not.
I think it is legal. The evidence is that JDK 1.6.0_21 compiles it with options -source 1.5 -target 1.5. Can't you use JDK 1.6 with these options to compile and JRE 1.5 to run?
It crashes for me, too (JDK 1.5.0_12). It crashes for me even with:
public Object boozinga() {
boolean b = true;
Object res = b ? new int[1] : new String[1];
return res;
}
The difficulty for the compiler is that the type of b ? new int[1] : new String[1] is java.lang.Object & java.io.Serializable & java.lang.Cloneable.
The problem here is that the compiler has trouble to decide the type of the expression b ? new int[1] : new String[1]. I had something like this before (with 1.1.8 or 1.2, I think - but with a real error message, not a compiler crash), and then simply used a cast to help the compiler here.
res[0] = b ? (Object)new int[1] : new String[1];
I didn't look what the language specification says about this - but the compiler should never crash with an exception, it should give a real error message.
Related
I have Java 19, and I am attempting to do some simple pattern-matching on a record that I created. However, Java is giving me a very confusing compilation error. Here is the simplest example I could make that causes the error.
public class ExpressionTypeIsASubsetOfPatternType
{
public record Triple(int a, int b, int c) {}
public static void main(String[] args)
{
System.out.println("Java Version = " + System.getProperty("java.version"));
final Triple input = new Triple(1, 2, 3);
if (input instanceof Triple t)
{
System.out.println("Made it here");
}
}
}
And here is the error that it gives me when I try to run/compile.
$ java ExpressionTypeIsASubsetOfPatternType.java
ExpressionTypeIsASubsetOfPatternType.java:15: error: expression type Triple is a subtype of pattern type Triple
if (input instanceof Triple t)
^
1 error
error: compilation failed
Surprisingly enough, googling this error showed up nothing useful. I am so used to punching in an error and immediately seeing the problem. I imagine that it is because this feature is so new.
Anyways, the closest thing I could find is a bug that is related, but definitely not the same issue that I am dealing with.
Finally, here is the relevant info about my java version.
$ java --version
openjdk 19 2022-09-20
OpenJDK Runtime Environment (build 19+36-2238)
OpenJDK 64-Bit Server VM (build 19+36-2238, mixed mode, sharing)
$ javac --version
javac 19
Java is just being "nice": it recognizes that the test will always succeed (because input is known to be a Triple, which is already a subtype of the test type Triple), so it produces an error telling you that you're doing something useless (with a roundabout message).
This is the same idea that makes
void foo() {
return;
return; // error: unreachable statement
}
an error: there is a useless piece of code that might indicate (serious) programmer error, so the compiler forces you to rethink the code.
The relevant section of the JLS is 15.20.2, which says
InstanceofExpression:
...
RelationalExpression instanceof Pattern
...
The following rules apply when instanceof is the pattern match operator:
...
If the type of the RelationalExpression is a subtype of the type of the Pattern, then a compile-time error occurs.
I.e. this is indeed an intended part of the language and not just a compiler bug or something.
I am using the below code to walk a directory and fetch the first file . I am not able to fix the two sonar lint issues . Please help.
List<String> result = walk.filter(Files::isRegularFile).map(x -> x.toString()).collect(Collectors.toList());
Please make this change:
List<String> result = walk.filter(p -> p.toFile().isFile()).map(Path::toString).collect(Collectors.toList());
SonarLint also state the reason for the suggestion.
Lambdas should be replaced with method references
Java 8's "Files.exists" should not be used
Look at the 3725 Sonar rule :
The Files.exists method has noticeably poor performance in JDK 8, and
can slow an application significantly when used to check files that
don't actually exist.
The same goes for Files.notExists, Files.isDirectory and
Files.isRegularFile.
Note that this rule is automatically disabled when the project's
sonar.java.source is not 8.
Your project very probably relies on JDK/JRE 8.
If you dig into the OpenJDK issues you could see that on Linux the issue was partially solved but not on Windows.
About the second issue :
map(x -> x.toString())
Just replace it by a method reference :
map(Path::toString)
So finally to be compliant with Sonar, it gives :
//FIXME use Files::isRegularFile when update with Java>8
List<String> result = walk.filter(p -> p.toFile().exists())
.map(Path::toString)
.collect(Collectors.toList());
I want to convert a stream into a list. To do so I have tried this code :
try(Stream<String> stream = Files.lines(Paths.get(args[0]))) {
List<String> lines = stream.collect(Collectors.toList());
}
But then the compiler tell me that :
Type mismatch: cannot convert from List<Object> to List<String>
Also I've tried this way :
try(Stream<String> stream = Files.lines(Paths.get(args[0]))) {
List<String> lines = Stream.of(stream).collect(Collectors.toList());
}
But then I have this error :
This static method of interface Stream can only be accessed as Stream.of
which happen every time, whenever I use the Stream.of methods.
Can someone help me out, please?
It's seems that you use java compiler language level lower than 8.
Try compiling from command line with
javac -source 8
Also check your language level project setting in IDE.
For example, output from IDEA 2016 hides info about used language level, but provide info about javac version
Information:Using javac 1.8.0_101 to compile java sources
Information:java: Errors occurred while compiling module 'demo_04'
Information:8/1/16 2:13 PM - Compilation completed with 1 error and 0 warnings in 1s 403ms
/tmp/1/src/JavaStreamExample.java
Error:(16, 49) java: incompatible types: java.util.List<java.lang.Object> cannot be converted to java.util.List<java.lang.String>
While compiling the code I get an unexpected error, which never occurred before, it says that I cannot convert from int to an Object...
Code:
maxBundles = max;
bundleProgressBar.setMaximum(max);
bundleProgressLabel.setText("Updating Components...");
// Tell JS that the state is Installing.
Object[] arr = { 1 };
error:
`103: error: incompatible types
[javac] Object[] arr = { 1 };`
I know this is a problem with eclipse, because it worked before, so my question is what can I change to resolve it...
What you're trying to do is called autoboxing - the process of converting a primitive (int in this case) to its Object represantation (Integer in this case), automatically. More on autoboxing and unboxing here.
Autoboxing was introduced in Java 1.5. So check that your project's compiler compliance level is set to 1.5 or above (Project properties -> Java compiler).
I get from github java project. I have java 1.7 version
there is code like this:
protected Set<Tag> tags = null;
private final Map<Tag, String> results;
protected AbstractAction() {
this.tags = new HashSet<>();
this.results = new HashMap<>();
}
I added it to eclipse, but there is error on new HashSet<>();
The error in eclipse is :
Multiple markers at this line
- Cannot instantiate the type HashSet
- Syntax error on token "<", ? expected after this token
- Type mismatch: cannot convert from HashSet to Set
- Syntax error on token "<", ? expected after this token
How do you think I can resolve it ?
Thank you.
The type inference feature was introduced in Java 7, and your code compiles correctly using the Java 7 JDK. Make sure you have configured the Java version level in the Eclipse project for Java 7 and not some earlier version.