You press compile, and before your program even starts, Java refuses:
Main.java:7: error: incompatible types: String cannot be converted to int
int hours = scanner.nextLine();
^
1 errorThe good news: this is a compile error. Java found the problem before running anything, and it tells you the exact file, line and spot. Here's what it means, the usual causes, how to fix each one, and the related errors you're likely to meet next.
What the error means
Main.java:7: the file and the line number.incompatible types: you put a value of one type into a place meant for another type.String cannot be converted to int: the value is aString(text), and the place, here the variablehours, is anint(a whole number). Java won't turn one into the other on its own.
The ^ mark shows where Java noticed it: at the end of scanner.nextLine(), the expression that produced the text.
Java checks types very strictly. A variable declared as int can only ever hold a whole number, so Java stops you as soon as you try to put text in it.
The same error with java.lang.String
Depending on your editor, the same message can look a little different, for example:
java: incompatible types: java.lang.String cannot be converted to intjava.lang.String is simply the full name of String (the class lives in the package java.lang), and the java: at the start only says that the message comes from the Java compiler. It's the same error, with the same causes and the same fixes.
Cause 1: reading a number with nextLine()
This is the most common one. You ask a question with a Scanner and want the answer as a number:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("How many hours a day are you on your phone? ");
int hours = scanner.nextLine();
System.out.println("That is " + hours * 365 + " hours a year.");
}
}scanner.nextLine() always gives back the whole line the user typed as a String, even if they typed only digits like 3. The text "3" isn't the number 3, so it can't go into an int. The same goes for scanner.next(), which reads one word: it also gives back a String.
The fix: Integer.parseInt
Read the line as text, then convert it with Integer.parseInt:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("How many hours a day are you on your phone? ");
int hours = Integer.parseInt(scanner.nextLine());
System.out.println("That is " + hours * 365 + " hours a year.");
}
}How many hours a day are you on your phone? 3
That is 1095 hours a year.Read it from the inside out: nextLine() gives the text "3", Integer.parseInt turns it into the number 3, and that number goes into hours.
What about nextInt()?
Scanner also has nextInt(), which reads a number directly, so it seems like the simpler fix. It works, but it has a trap that catches almost everyone. Ask for a number with nextInt() and then for a name with nextLine():
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Hours a day? ");
int hours = scanner.nextInt();
System.out.print("Your name? ");
String name = scanner.nextLine();
System.out.println("Name: [" + name + "], hours: " + hours);
}
}Type 3, press Enter, and the program doesn't wait for your name at all:
Hours a day? 3
Your name? Name: [], hours: 3nextInt() reads the 3 but leaves the Enter you pressed behind. The next nextLine() finds that leftover line break straight away and returns an empty line. That's why reading every answer with nextLine() and converting with Integer.parseInt is the safer habit. (If you do use nextInt(), call scanner.nextLine(); once right after it to throw away the rest of the line.)
Cause 2: a value in quotes
The same error appears when you write a value in double quotes by mistake. Anything in double quotes is a String:
int age = "thirty";Main.java:3: error: incompatible types: String cannot be converted to int
int age = "thirty";
^
1 errorHere the ^ points at the text itself. The fix depends on what you meant: a number goes without quotes, int age = 30;, and if you really want text, the variable must be a String: String age = "thirty";.
Cause 3: a method that returns a String
A method's return type decides what its result is, wherever you use it. If a method is declared to return a String, you can't put its result into an int:
public class Main {
static String askName() {
return "Lena";
}
public static void main(String[] args) {
int count = askName();
}
}Main.java:7: error: incompatible types: String cannot be converted to int
int count = askName();
^
1 errorLook at the method's first line, static String askName(): the String before the name is what it gives back. Either store the result in a String, or, if the method should really give a number, change its return type and what it returns.
What can happen next: NumberFormatException
Once the program compiles, try typing 2.5 as the answer:
How many hours a day are you on your phone? 2.5
Exception in thread "main" java.lang.NumberFormatException: For input string: "2.5"
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
at java.base/java.lang.Integer.parseInt(Integer.java:668)
at java.base/java.lang.Integer.parseInt(Integer.java:786)
at Main.main(Main.java:7)This is a different kind of problem. The code compiled fine, but while running, Integer.parseInt got text that isn't a whole number. That's called an exception, and the last at line shows where it came from in your code: Main.java:7.
You have two options:
- If decimals are allowed, use a
doubleandDouble.parseDoubleinstead. - If you need a whole number, catch the exception and ask nicely:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("How many hours a day are you on your phone? ");
String text = scanner.nextLine();
try {
int hours = Integer.parseInt(text);
System.out.println("That is " + hours * 365 + " hours a year.");
} catch (NumberFormatException e) {
System.out.println("Please type a whole number, like 3.");
}
}
}How many hours a day are you on your phone? 2.5
Please type a whole number, like 3.Related errors
The same "incompatible types" message comes in a few other flavours. Each one names the two types, so read them the same way: the value's type first, then the type of the place it's going.
int cannot be converted to String
The opposite direction:
int hours = 3;
String label = hours;Main.java:4: error: incompatible types: int cannot be converted to String
String label = hours;
^
1 errorTurn the number into text with String.valueOf(hours), or join it to some text with +, which makes the whole thing a String:
String label = String.valueOf(hours); // "3"
String sentence = "Hours: " + hours; // "Hours: 3"String cannot be converted to double
The same problem with a decimal number, for example double price = scanner.nextLine();. The fix is the decimal version of parseInt:
double price = Double.parseDouble(scanner.nextLine());String cannot be converted to char
char grade = "A";Main.java:3: error: incompatible types: String cannot be converted to char
char grade = "A";
^
1 errorIn Java, double quotes make a String, and single quotes make a single character, a char. Write char grade = 'A';. If you have a String and want its first character, use text.charAt(0).
possible lossy conversion from double to int
int total = 7;
int average = total / 2.0;Main.java:4: error: incompatible types: possible lossy conversion from double to int
int average = total / 2.0;
^
1 error7 / 2.0 is 3.5, a double, and putting it into an int would lose the .5. Java won't do that silently. Either keep the decimals with double average = total / 2.0;, or say that you really want to cut them off with a cast: int average = (int) (total / 2.0);, which gives 3.
Compile errors and exceptions
It helps to keep the two apart:
- A compile error like
incompatible typesstopsjavacbefore anything runs. It always haserror:and a line number in your file. - An exception like
NumberFormatExceptionhappens while the program runs, often because of the input. It starts withException in thread "main".
Both point you to a line in your code. Start there. For the exception you'll probably meet soon after this one, see Java NullPointerException.
A quick checklist
- Read the two types in the message: the first is the value you have, the second is what the variable (or parameter) expects.
- Find where the value comes from:
nextLine()andnext()always give aString, so does anything in double quotes, and so does a method declared to returnString. - Convert on purpose:
Integer.parseIntorDouble.parseDoublefor text to numbers,String.valueOffor numbers to text, single quotes for achar. - Prefer
nextLine()plusparseIntovernextInt(), or clear the line afternextInt(). - Once it compiles, test with input you didn't expect, like
2.5or a word, and handle theNumberFormatException.
