Warning: compile with -Xlint:unchecked pops on this code! - java

import java.lang.reflect.Method;
public class ClassLoadingTester
{
public static void main(String a[]){
try{
ClassLoader loader=new CustomClassLoader();
Class c=loader.loadClass("AddClass");
loader=null;
Object o=c.newInstance();
Method m=c.getMethod("getTwoNumbers",new Class[]{String.class,String.class});
m.invoke(o,new Object[]{"2","3"});
}catch(Exception e){
e.printStackTrace();
}
}
}
This code snippet generates a warning when i compile in java.
I think it pertains to this line,
Method m=c.getMethod("getTwoNumbers",new Class[]{String.class,String.class});
When I attempt to put <String> like this new Class<String>[]{String.class,String.class}
It generates an error saying generic array type I'm doing my code in BlueJ.
But when I leave the code as is it generates that irritating warning ^^.
I just want to get rid of that warning what should I do with that line of code?

You can't create arrays of generic types like Class<String>, hence the error. So you don't have much choice other than adding a #SuppressWarnings("unchecked") annotation before the statement to silence the warning.
Note that these warnings almost always have a reason, and silencing them this way regularly may easily result in runtime class cast exceptions! So always think three times before using #SuppressWarnings("unchecked") - use it only when you are absolutely sure the cast is safe and there can be no negative consequences. In this case it looks safe to me to use it.

int t=10, a=7, b=52, d=97;
if((t + d) / 2 > b && (d - t) % 2 != 0)
if(a%2==0 || b%2==0)
System.out.println(--t + a);
else
System.out.println(--t - a);
else
System.out.println(t + ++a);

Related

Why do assertions in Java act as a "missing return statement" whereas throw statements do not?

I have a class with the following field and method:
private final Map<Character, String> charMap = new LinkedHashMap<>();
public Character charOf(String s) {
assert this.charMap.containsValue(s);
for (Character c : this.charMap.keySet()) {
if (this.charMap.get(c).equals(s)) return c;
}
}
The compiler doesn't like this, giving me a "missing return statement" error, whereas this compiles fine:
private final Map<Character, String> charMap = new LinkedHashMap<>();
public Character charOf(String s) {
for (Character c : this.charMap.keySet()) {
if (this.charMap.get(c).equals(s)) return c;
}
throw new IllegalArgumentException("There is no mapping for \"" + s + "\"");
}
As far as I can tell, these two methods should function exactly the same and do the exact same thing with the former being slighly more readable (at the expense of a less detailed error message). It will always either return a value or throw an exception. Why does the compiler not realize this?
There are two reasons:
The complier is not 'smart' enough to figure out that this.charMap.containsValue(s) being true means this.charMap.get(c).equals(s) must be true for some c. It only does simpler analysis, like checking if both branches of an if-statement have a return in them.
Even if it were smart enough, Java is a language with mutable objects and threads - even if the map contains the key at the time of the assert, it may be removed from the map by another thread before the loop starts.
If you want a language with a sufficiently 'smart' compiler, you might want to look at dependently-typed languages like Idris.
Because of two things:
Firstly, assertions only throw exceptions if they are enabled at run-time using the jvm argument -ea. This means there is a possibility that is skipped.
Secondly, you throw the exception at the end while you run the assertion before the code. Theoretically, the assertion could be true without the loop returning as the Map content could theoretically change between the assertion and the loop or containsValue could do something the compiler doesn't expect. The compiler just checks for sytax, not for logical impossibilities.
This has more to do with JLS: https://docs.oracle.com/javase/specs/jls/se10/html/jls-8.html#jls-8.4.7 than with assert:
If a method is declared to have a return type (§8.4.5), then a
compile-time error occurs if the body of the method can complete
normally (§14.1).
In other words, a method with a return type must return only by using
a return statement that provides a value return; the method is not
allowed to "drop off the end of its body". See §14.17 for the precise
rules about return statements in a method body.
Since your method must return a value (not void), only return or throw return the execution flow to the caller.
This rule ensure you avoid such case (this is a C example):
#define N = 10;
const char* CHAR_MAP[N] = ...;
const char CHAR_VALUE[N] = ...;
char charOf(const char* s) {
for (int i = 0; i < N; ++i) {
if (strcmp(s, CHAR_MAP[i]) == 0) {
return CHAR_VALUE[i];
}
}
// not return value
}
My C is a bit rusty, this might not compile but the point is: in C - at least in C99 - the value returned in this case is undefined which may lead to several nasty problems, especially with pointers.
The rule in Java ensure that you always:
Return a value, eg: null.
Throw an exception, meaning an error.
This does not means the returned value will make thing works: returning null here may produce NullPointerException.
Beside, on a side note:
public Character charOf(String s) {
for (Map.Entry<Character,String> entry : this.charMap.entrySet()) {
if (s.equals(entry.getValue()) {
return entry.getKey();
}
}
throw new IllegalArgumentException("There is no mapping for \"" + s + "\"");
}
You should avoid mixing keySet() and get() when you can use entrySet().

Where to check for values and throw an exception

Let's say I have a class like the following one:
public class Parameter {
private double[] parameterValues;
public Parameter(double[] parameterValues) throws BadElementInitializationException {
checkParameterValues(parameterValues);
this.parameterValues = parameterValues;
}
public double[] getParameterValues() {
return parameterValues;
}
public void setParameterValues(double[] parameterValues) throws BadElementInitializationException {
checkParameterValues(parameterValues);
this.parameterValues = parameterValues;
}
private void checkParameterValues(double[] parameterValues) throws BadElementInitializationException {
if(parameterValues == null)
throw new BadElementInitializationException("Parameter values cannot be null");
if(parameterValues.length == 0)
throw new BadElementInitializationException("Parameter values cannot be empty");
}
public int noOfValues(){
return parameterValues.length;
}
}
And the array is later used to perform some calculations.
My question is, where should I check that parameterValues is not null, nor empty? Should I do that in the Parameter class, like I did, or should I do that in the class which performs calculations?
Moreover, should I throw an exception here, or in the Calculation class? And what would be the reason to throw checked and what to throw unchecked exception? My goal is to make a stable application that won't crash easily.
You should do it in all places where getting an null or empty array is not valid. If you do it just in your Parameter class and rely on this having done the check in your Calculator class, then what if you start to use your Calculator class somewhere else? Who are you going to rely on to do the checks there? If you do it in the Calculator class and then refactor the Parameters class to use something else in the future, then your check will go away.
If its also invalid to have a null or empty array in your Calculator class then you need to check there as well.
Alternatively pass an object to both which cannot be empty and then you only need to make the null check.
Should I do that in the Parameter class, like I did, or should I do
that in the class which performs calculations?
In my opinion, better to check in Parameter class then any other classes. You could see how it do in google guava , for example, in most class they use:
public static boolean isPowerOfTwo(BigInteger x) {
checkNotNull(x);
return x.signum() > 0 && x.getLowestSetBit() == x.bitLength() - 1;
}
or
public static int log2(BigInteger x, RoundingMode mode) {
checkPositive("x", checkNotNull(x));
...
Moreover, should I throw an exception here, or in the Calculation
class?
If you check your parameters in Parameter class, better throw in Parameter class also. In addition to, you may use some standart function to check and throw exception, for example from google guava:
com.google.common.base.Preconditions.checkNotNull
com.google.common.base.Preconditions.checkArgument
com.google.common.math.MathPreconditions.checkPositive
And what would be the reason to throw checked and what to throw
unchecked exception?
A checked exception is good if you think that you must catch and working this exception later. In most case, for wrong parameters quite enough unchecked exception, like standart IllegalArgumentException in Java. Also, a checked exception need to say other programmers (who use this API) that this exception could be happened, and they need to working with it. Working with an unchecked exception is quite easy for programmer (and often reduce your source code), however a checked exception become your code is more reliable.
A more info about checked and uncheked exceptions, you could find in this post

The method access$110(GameHandler) is undefined for the type GameHandler

Okay, so I have an error that keeps bugging me and I don't know how to fix it.. So would be glad if u could help me with it. The error? Read the title. :P
public void run()
{
if (GameHandler.this.timelimit < 0)
{
for (Player player : GameHandler.this.arena.getPlayersManager().getPlayersInArena())
{
GameHandler.this.arena.getPlayerHandler().leavePlayer(player, Messages.arenatimeout, "");
}
GameHandler.this.stopArena();
return;
}
if (GameHandler.this.arena.getPlayersManager().getPlayersCount() == 0)
{
GameHandler.this.stopArena();
return;
}
for (Player player : GameHandler.this.arena.getPlayersManager().getPlayersInArena())
{
Bars.setBar(player, Bars.playing, GameHandler.this.arena.getPlayersManager().getPlayersCount(), GameHandler.this.timelimit / 20, GameHandler.this.timelimit * 5 / GameHandler.this.arena.getStructureManager().getTimeLimit());
GameHandler.this.handlePlayer(player);
}
GameHandler.access$110(GameHandler.this); //**Error is here. ("access$110")**
}
This error message means that you code wasn't compiled correctly. The access$xxx methods are generated by the compiler to allow it to access private members of other classes which the JVM doesn't actually support.
To get this class to compile if you decompiled it, you have to recompile all the classes which came from the same file, not just one as it is more than likely different classes were assign different accessor methods.

Converting String to Integers the safe way

I have a little method that amongst other things also converts a string into an integer. Since the string is a parameter of the method I want to make sure that that string is convertable. So I was just wondering what would be the safest and / or fastest way.
Version A: Just leave it as it is and take the risks (which I'm trying to avoid)
public static int stringToInt(String param) {
return Integer.valueOf(param);
}
(in terms of speed, what kind of difference would it make to version B and C?)
Version B: Catch the exception
public static int stringToInt(String param) {
try {
return Integer.valueOf(param);
} catch(NumberFormatException e) {
return -1;
}
}
Version C: Check each letter of the string to see, if it's a digit number or not
public static int stringToInt(String param) {
for(char c : param.toCharArray()) {
if(!Character.isDigit(c))
return -1;
}
return Integer.valueOf(param);
}
Note that the parameter has to be a positive number and the -1 is supposed to be the "error value" in my little program, in other words, all three versions of methods would work perfectally fine in my program.
I'm very open to any other suggestion you can give me, so feel free to create your own version, if you think yours is better.
Thank you very much for your support in advance.
Guava offers a utility method for this which returns null in case your String can't be parsed.
https://google.github.io/guava/releases/19.0/api/docs/com/google/common/primitives/Ints.html#tryParse(java.lang.String)
Integer result = Ints.tryParse("1"); //returns 1
Integer result = Ints.tryParse("-1"); //returns -1
Integer result = Ints.tryParse("a"); //returns null
First, note that version C is not bulletproof: it would reject negative numbers, and would not catch numbers that are too large.
Version B is OK, yet it makes the caller change the coding style: rather than catching an error and processing it together with other errors, the caller would need to check for -1 all the time. This may be suboptimal in situations where you read multiple integers, but the error processing does not depend on which particular one has failed. In addition, new coders using your API may forget to check for -1, and use the error code inadvertently.
That's why I would stay with the first option: the code using version A would look instantly familiar to anyone who knows Java API, without the need to learn what happens inside your function.
I believe a modified B to throw an exception rather than returning -1 will be the best choice. It is good to throw the exception up to the level, where it can be processed to send the proper response to the user. Returning a value like -1 will make your code error prone. Assume that a different programmer is consuming your method and he/she just have the signature of your method. So it is not clear from the signature what he/she should code to handle an exception or error scenario. But if you throw the exception and add it to your method declaration then it will enable the other programmer to consume your method properly alongwith the required exception handling. For me this looks the best:
public static int stringToInt(String param) throws NumberFormatException {
try {
return Integer.valueOf(param);
} catch(NumberFormatException e) {
// return -1;
throw e;
}
}
Java 8 without any API:
Optional.ofNullable(strNum)
.map(Integer::valueOf).orElse(null);
public int stringToInt(String param) throws NumberFormatException {
Optional.ofNullable(param.replaceAll("\\s+", ""))
.map(Integer::valueOf).orElse(null);
/*
or
Optional.ofNullable(param.replaceAll(" ", ""))
.map(Integer::valueOf).orElse(null);
*/
}
use the replaceAll to replace white spaces the plus is cpu friendly even though seems not needed.
I used a combination of 2 answers to have it safe for nulls, empty or blank strings, and non numeric characters:
public static Integer safeStringToInt(String param) {
return Optional.ofNullable(param).map(Ints::tryParse).orElse(null);
}

what does Dead Code mean under Eclipse IDE Problems Section

I am using Eclipse Helios IDE for our Web Application development.
Under Problems section in Eclipse, for some of lines the description is displayed as "Dead Code".
Could anybody please tell me what does Dead Code actually mean ?
Please see the screen shot for your reference.
For example this part is shown as dead code under Eclipse
else {
int length;
if (ar != null)
length = Array.getLength(ar);
else
length = 0; // This line is dead code
In Eclipse, "dead code" is code that will never be executed. Usually it's in a conditional branch that logically will never be entered.
A trivial example would be the following:
boolean x = true;
if (x) {
// do something
} else {
// this is dead code!
}
It's not an error, because it's still valid java, but it's a useful warning, especially if the logical conditions are complex, and where it may not be intuitively obvious that the code will never be executed.
In your specific example, Eclipse has calculated that ar will always be non-null, and so the else length = 0 branch will never be executed.
And yes, it's possible that Eclipse is wrong, but it's much more likely that it's not.
Dead code is code that will never be executed, e.g.
boolean b = true
if (!b) {
....
// dead code here
}
Dead code means, that there is no way that this code will be executed.
Sometimes you even can't compile it (like this case:)
private Boolean dead_code()
{
return true;
//Dead code below:
dosomething();
}
But in other cases this is not too obvious, eg this statement:
b=true;
[...]
if (b==false)
{
//Dead code
}
If you have this message, there is some major flaw in your code. You have to find it, otherwise your app won't work as intended.
There are two kinds of diagnostics that Eclipse gives out for marking code that will/may not be executed at runtime.
1) Unreachable code: These are the usual java warnings that follow the unreachability rules of the JLS, and are also given by javac. These are meant to be compile errors. Examples:
int foo() {
return 1;
int i = 1; // Unreachable
}
int foo2() {
while (true);
int i =1; //Unreachable
}
There are other more complicated examples :)
2) Dead code: This is Eclipse's own static analysis warnings, and are mostly tied out of the null analysis i.e.
void foo() {
Object o = null;
if (o == null) {
} else {
// dead code
}
The examples given above should NOT give a dead code warning. i.e.
boolean x = true;
if (x) {
// do something
} else {
// this is dead code!
}
should not give the warning, because JLS forbids the compiler to evaluate the 'value' of variables. All that we can evaluate is the 'nullness'
Hope this helps
You might be having an Null pointer exception in the lines above the "Dead Code" lines.
Make sure you check for "Null Pointer" exception.
It is possible that you have used the variable ar before. Then the compiler knows that the line in the else statement will never be executed. Either there will be a NullPointerException at the place where you used ar or the first part of the if statement will be executed.
let me give some answer for the dead code.
Eg:
public class UnreachableTest{
public static void main(){
try{
// some code
}
catch(Exception exc){
throw new NullPointerException();
System.out.println("Unreachable line"); // compile time error
}
}
}
here the System.out.println("Unreachable line"); is never executed.
Which in turn considered to be a dead code.
Another example may be:
int func(int i, int j)
{
int sum = i + j;
return i + j; // never actually using the sum
}
simple the function returns i + j; never really uses sum.
Sum is considered to be dead code here.
Some other case when this happens.
System.out.println("result :" + result + ":" + result.isEmpty());
if (result == null)
return result;
else if(!result.isEmpty())
str.append(result + " ");
1) Here as you you are printing result and checking isEmpty() eclipse assumes that result is not null so it will not go in if. So return result is dead code.
2)Now let say result is coming null so you will get NullPointerException in result.isEmpty() so again it will not go in if and return result is deadcode
To make this work just comment out System.out.println().
Eclipse gives this warning if the condition check you are giving may never be satisfied. Following are some examples
Object o=null;
if(o!=null) {
//Some code
}
Here Dead code warning will come as Object is already made null
Another example is given below
BSTTest bstTest=null;
bstTest.test=10;
if(bstTest==null) {
//some code
}
Here the code is trying to access a variable of the class. As the variable is already accessed, eclipse will give dead code warning in if(bstTest==null) as bstTest may not be null when the variable is already accessed.
Note: Here bstTest.test will give null pointer exception
Simple Example of Dead Code
public class IfTest {
public static void main(String[] args) {
if (true) {
if(false) {
System.out.println("a"); //Dead code, Never be Execute this if block.
}else {
System.out.println("b");
}
}
}
To simplify the term's Unreachable code and dead code:
Unreachable Code is a code block/statement in Java to which the control never reaches and never gets executed during the lifetime of the program. Following is the example of unreachable code. This generates compiler time error.
public void unreachableCodeExample() {
System.out.println("This will execute");
return;
System.out.println("This will not"); //This is Unreachable code
}
While A Dead code is an unreachable code, but it doesn’t generate compile time error. But if you execute it in eclipse (Or some other IDE) it gives you a warning. See below example,
public void deadCodeExample() {
if (true) {
System.out.println("This will execute");
return;
}
System.out.println("This will not"); //This is dead code
}
Dead code is the section of our code that is never going to execute runtime, its useless
EX:
if(false){ // statements }
For more example u can refer : DeadCode Examples
Try this:
while (true) {
if(false == true) break;
}
S.O.P("I will never reach here!") <-- This code will never be executed.
The code is valid as it conform to the compiler, however in reality the loop will never exit, and in effect S.O.P will never be executed.

Categories

Resources