Error incompatible types object cannot be converted to

The Java incompatible types error happens when a value assigned to a variable or returned by a method is incompatible with the one declared.

Introduction to Data Types & Type Conversion

Variables are memory containers used to store information. In Java, every variable has a data type and stores a value of that type. Data types, or types for short, are divided into two categories: primitive and non-primitive. There are eight primitive types in Java: byte, short, int, long, float, double, boolean and char. These built-in types describe variables that store single values of a predefined format and size. Non-primitive types, also known as reference types, hold references to objects stored somewhere in memory. The number of reference types is unlimited, as they are user-defined. A few reference types are already baked into the language and include String, as well as wrapper classes for all primitive types, like Integer for int and Boolean for boolean. All reference types are subclasses of java.lang.Object [1].

In programming, it is commonplace to convert certain data types to others in order to allow for the storing, processing, and exchanging of data between different modules, components, libraries, APIs, etc. Java is a statically typed language, and as such has certain rules and constraints in regard to working with types. While it is possible to convert to and from certain types with relative ease, like converting a char to an int and vice versa with type casting [2], it is not very straightforward to convert between other types, such as between certain primitive and reference types, like converting a String to an int, or one user-defined type to another. In fact, many of these cases would be indicative of a logical error and require careful consideration as to what is being converted and how, or whether the conversion is warranted in the first place. Aside from type casting, another common mechanism for performing type conversion is parsing [3], and Java has some predefined methods for performing this operation on built-in types.

double myDouble = 9; // Automatic casting (int to double)
int myInt = (int) 9.87d; // Manual casting (double to int)
boolean myBoolean = Boolean.parseBoolean("True"); // Parsing with a native method (String to boolean)

System.out.println(myDouble);   // 9.0
System.out.println(myInt);      // 9
System.out.println(myBoolean);  // true

Incompatible Types Error: What, Why & How?

The incompatible types error indicates a situation where there is some expression that yields a value of a certain data type different from the one expected. This error implies that the Java compiler is unable to resolve a value assigned to a variable or returned by a method, because its type is incompatible with the one declared on the variable or method in question. Incompatible, in this context, means that the source type is both different from and unconvertible (by means of automatic type casting) to the declared type.

This might seem like a syntax error, but it is a logical error discovered in the semantic phase of compilation. The error message generated by the compiler indicates the line and the position where the type mismatch has occurred and specifies the incompatible types it has detected. This error is a generalization of the method X in class Y cannot be applied to given types and the constructor X in class Y cannot be applied to given types errors discussed in [4].

The incompatible types error most often occurs when manual or explicit conversion between types is required, but it can also happen by accident when using an incorrect API, usually involving the use of an incorrect reference type or the invocation of an incorrect method with an identical or similar name.

Incompatible Types Error Examples

Explicit type casting

Assigning a value of one primitive type to another can happen in one of two directions. Either from a type of a smaller size to one of a larger size (upcasting), or from a larger-sized type to a smaller-sized type (downcasting). In the case of the former, the data will take up more space but will be intact as the larger type can accommodate any value of the smaller type. So the conversion here is done automatically. However, converting from a larger-sized type to a smaller one necessitates explicit casting because some data may be lost in the process.

Fig. 1(a) shows how attempting to assign the values of the two double variables a and b to the int variables x and y results in the incompatible types error at compile-time. Prefixing the variables on the right-hand side of the assignment with the int data type in parenthesis (lines 10 & 11 in Fig. 1(b)) fixes the issue. Note how both variables lost their decimal part as a result of the conversion, but only one kept its original value—this is exactly why the error message reads possible lossy conversion from double to int and why the incompatible types error is raised in this scenario. By capturing this error, the compiler prevents accidental loss of data and forces the programmer to be deliberate about the conversion. The same principle applies to downcasting reference types, although the process is slightly different as polymorphism gets involved [5].

(a)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package rollbar;

public class IncompatibleTypesCasting {

  public static void main(String... args) {
    double a = 10.5;
    double b = 5.0;
    System.out.println("a: " + a + "tb: " + b);

    int x = a;
    int y = b;
    System.out.println("x: " + x + "ty: " + y);
  }
}
IncompatibleTypesCasting.java:10: error: incompatible types: possible lossy conversion from double to int
    int x = a;
            ^
IncompatibleTypesCasting.java:11: error: incompatible types: possible lossy conversion from double to int
    int y = b;
            ^
2 errors

(b)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package rollbar;

public class IncompatibleTypesCasting {

  public static void main(String... args) {
    double a = 10.5;
    double b = 5.0;
    System.out.println("a: " + a + "tb: " + b);

    int x = (int) a;
    int y = (int) b;
    System.out.println("x: " + x + "ty: " + y);
  }
}
a: 10.5 b: 5.0
x: 10   y: 5
Figure 1: Incompatible types when downcasting (a) error and (b) resolution

Explicit parsing

Parsing is a more complex process than type casting as it involves analyzing the underlying structure of a given data before converting it into a specific format or type. For instance, programmers often deal with incoming streams of characters, usually contained in a string that needs to be converted into specific types to make use of in the code. A common scenario is extracting numeric values from a string for further processing, which is where parsing is routinely used.

The main method in Fig. 2(a) declares the variable date which holds the current date as a String in the yyyy-MM-dd format. In order to get the year value into a separate variable it is necessary to “parse” the first 4 characters of the string, and this can be accomplished by splitting the string by specifying the “-” character as a delimiter and then accessing the first element (line 9 in Fig. 2(a)). With this, the year value has been successfully parsed and stored into a new variable. Attempting to increase the value of this new variable and store the resulting value in a separate int variable triggers the incompatible types error (line 10 in Fig. 2(a)). This is because even though the year has been isolated from the date and parsed into a new variable, it is impossible to perform arithmetic operations on a variable of type String. Therefore, it is necessary to represent this value as a numeric type. The best way to do this is to use Java’s built-in Integer::parseInt method which takes a String argument and converts it to an int (line 10 in Fig. 2(b)). (Note that if the given argument is not a valid integer value, this method will throw an exception.) Now that the year has been manually and explicitly parsed from the initial date string into an integer value that can be incremented, the program compiles and prints the expected message, as shown in Fig. 2(b).

(a)

1
2
3
4
5
6
7
8
9
10
11
12
13
package rollbar;

import java.time.LocalDate;

public class IncompatibleTypesParsing {

 public static void main(String... args) {
   String date = LocalDate.now().toString(); // "2021-12-21"
   String year = date.split("-")[0]; // "2021"
   int newYear = year + 1;
   System.out.println("Happy New Year " + newYear + "!");
 }
}
IncompatibleTypesParsing.java:10: error: incompatible types: String cannot be converted to int
    int newYear = year + 1;
                       ^
1 error

(b)

1
2
3
4
5
6
7
8
9
10
11
12
13
package rollbar;

import java.time.LocalDate;

public class IncompatibleTypesParsing {

  public static void main(String... args) {
    String date = LocalDate.now().toString();
    String year = date.split("-")[0];
    int newYear = Integer.parseInt(year) + 1;
    System.out.println("Happy New Year " + newYear + "!");
  }
}
Happy New Year 2022!
Figure 2: Incompatible types when parsing (a) error and (b) resolution

Incorrect type assignments

Sometimes, the incompatible types error can occur due to basic negligence, where the only mistake is an accidental mis-declaration of a variable’s type (Fig. 3(a)). In these instances, the issue is quite obvious and simply correcting the type declaration solves the problem (Fig. 3(b)).

(a)

package rollbar;

public class IncompatibleTypesAssignment {

 public static void main(String... args) {
   int greeting = "Merry Christmas!";
   System.out.println(greeting);
 }
}
IncompatibleTypesAssignment.java:6: error: incompatible types: String cannot be converted to int
    int greeting = "Merry Christmas!";
                   ^
1 error

(b)

package rollbar;

public class IncompatibleTypesAssignment {

 public static void main(String... args) {
   String greeting = "Merry Christmas!";
   System.out.println(greeting);
 }
}
Merry Christmas!
Figure 3: Incompatible types with incorrect assignment (a) error and (b) resolution

Incorrect method return types

A slightly less common but non-surprising occurence of the incompatible types error, especially when refactoring is involved, can be found in method return types. Namely, sometimes a method’s return statement ends up returning a value that doesn’t match the method’s declared return type (Fig. 4(a)). This issue has two possible remedies; either make the value returned match the return type (Fig. 4(b)), or change the method’s return type to match the actual value returned (Fig. 4(c)). And in the case of void methods (methods with no return type), one can simply get rid of the return statement if the return value is never used, as is the case with the example in Fig. 4.

(a)

1
2
3
4
5
6
7
8
9
10
11
12
13
package rollbar;

public class IncompatibleTypesReturn {

 public static void main(String... args) {
   printGreeting();
 }

 static void printGreeting() {
   System.out.println("Happy Holidays");
   return true;
 }
}
IncompatibleTypesReturn.java:11: error: incompatible types: unexpected return value
    return true;
           ^
1 error

(b)

1
2
3
4
5
6
7
8
9
10
11
12
package rollbar;

public class IncompatibleTypesReturn {

 public static void main(String... args) {
   printGreeting();
 }

 static void printGreeting() {
   System.out.println("Happy Holidays");
 }
}
Happy Holidays!

(c)

1
2
3
4
5
6
7
8
9
10
11
12
13
package rollbar;

public class IncompatibleTypesReturn {

 public static void main(String... args) {
   printGreeting();
 }

 static boolean printGreeting() {
   System.out.println("Happy Holidays");
   return true;
 }
}
Happy Holidays!
Figure 4: Incompatible types with incorrect return type (a) error and (b)(c) two solutions

Incorrect imports and similarly named reference types

It is not uncommon to come across classes or other reference types with the same or a similar name. In fact, this happens even within the standard Java API, and can baffle many programmers, beginners and experts alike. One such case is the List class which represents one of Java’s main collection data structures [6]. This reference type can easily come into collision with another type of the same name, but from a different package. Namely, that’s the java.awt.List class that is part of Java’s built-in AWT API for creating graphical user interfaces [7]. All it takes is accidentally importing the wrong package, and the compiler immediately complains about the type mismatch, raising the incompatible types error, as demonstrated in Fig. 5(a). Fixing the import on line 5, as shown in Fig. 5(b), sorts things out.

(a)

1
2
3
4
5
6
7
8
9
10
11
12
13
package rollbar;

import java.util.ArrayList;
import java.util.Arrays;
import java.awt.List;

public class IncompatibleTypesList {

 public static void main(String... args) {
   List songs = new ArrayList<String>(Arrays.asList("Silent Night", "Deck the Halls", "Jingle Bells", "Winter Wonderland"));
   System.out.println(songs);
 }
}
IncompatibleTypesList.java:10: error: incompatible types: ArrayList<String> cannot be converted to List
    List songs = new ArrayList<String>(Arrays.asList("Silent Night", "Deck the Halls", "Jingle Bells", "Winter Wonderland"));
                 ^
1 error

(b)

1
2
3
4
5
6
7
8
9
10
11
12
13
package rollbar;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class IncompatibleTypesList {

 public static void main(String... args) {
   List songs = new ArrayList<String>(Arrays.asList("Silent Night", "Deck the Halls", "Jingle Bells", "Winter Wonderland"));
   System.out.println(songs);
 }
}
[Silent Night, Deck the Halls, Jingle Bells, Winter Wonderland]
Figure 5: Incompatible types incorrect reference type (a) error and (b) resolution

Popular external libraries are also prone to naming their reference types similarly, so whenever relying on such a library for a certain feature or functionality it is important to pick one, or be careful not to confuse one for another, if multiple libraries are already being used.

Fig. 6(a) shows an example of passing a JSON type object to a method as an argument. Here, the method printJson expects an argument of type JsonObject, but the calling method tries to pass in an instance of the similarly named JSONObject reference type, part of a different library altogether. This results in the incompatible types error being raised by the compiler, with the alert org.json.JSONObject cannot be converted to javax.json.JsonObject pointing to the erroneous method call. Swapping the inappropriate constructor call with an instance of the correct type solves the issue, as shown in Fig. 6(b).

(a)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package rollbar;

import org.json.JSONObject;
import javax.json.JsonObject;
import java.util.Map;

public class IncompatibleTypesJson {

  public static void main(String... args) {
    Map<String, Object> jsonMap = Map.of(
        "name", "Saint Nicholas",
        "nicknames", new String[]{"Santa Claus", "Father Christmas"},
        "location", "North Pole"
    );

    JsonObject json = Json.createObjectBuilder(jsonMap).build();

    printJson(json);
}

  static void printJson(JSONObject jsonObject) {
    System.out.println(jsonObject.toString(4));
  }
}
IncompatibleTypesJson.java:18: error: incompatible types: 
javax.json.JsonObject cannot be converted to org.json.JSONObject
    printJson(json);
              ^

(b)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package rollbar;

import javax.json.Json;
import javax.json.JsonObject;
import java.util.Map;

public class IncompatibleTypesJson {

  public static void main(String... args) {
    Map<String, Object> jsonMap = Map.of(
        "name", "Saint Nicholas",
        "nicknames", new String[]{"Santa Claus", "Father Christmas"},
        "location", "North Pole"
    );

    JSONObject json = new JSONObject(jsonMap);

    printJson(json);
  }

  static void printJson(JSONObject jsonObject) {
    System.out.println(jsonObject.toString(4));
  }
}
{
    "name": "Saint Nicholas",
    "location": "North Pole",
    "nicknames": [
        "Santa Claus",
        "Father Christmas"
    ]
}
Figure 6: Incompatible types incorrect reference type (a) error and (b) resolution

Fig. 6 also serves as an example to show how the incompatible types error is, in fact, a generalization of the method X in class Y cannot be applied to given types error explored in [4]. Depending on the specific compiler that is being used and its configuration settings, either of these errors could be triggered in this kind of scenario.

Summary

As a strongly typed language, Java has strict rules regarding data types and how they interoperate. These rules affect variable assignment, method invocation, return values, etc. This makes Java code verbose, but at the same time quite secure, as it allows for many errors to be detected during compilation. One such error is the incompatible types error, which is directly tied to Java’s type system. This article provides some background into Java types and dives into the symptoms and causes behind the incompatible types error, by presenting a series of relevant examples tailored to bring clarity in understanding and successfully managing this error.

Track, Analyze and Manage Errors With Rollbar

Rollbar in action

Managing errors and exceptions in your code is challenging. It can make deploying production code an unnerving experience. Being able to track, analyze, and manage errors in real-time can help you to proceed with more confidence. Rollbar automates error monitoring and triaging, making fixing Java errors easier than ever. Sign Up Today!

References

[1] R. Liguori and P. Liguori, 2017. Java Pocket Guide, 4th ed. Sebastopol, CA: O’Reilly Media, pp. 23-46.

[2] W3schools.com, 2021. Java Type Casting. Refsnes Data. [Online]. Available: https://www.w3schools.com/java/java_type_casting.asp. [Accessed: Dec. 18, 2021]

[3] D. Capka, 2021. Lesson 3 — Variables, type system and parsing in Java, Ictdemy.com. [Online]. Available: https://www.ictdemy.com/java/basics/variables-type-system-and-parsing-in-java. [Accessed: Dec. 19, 2021]

[4] Rollbar, 2021. How to Fix Method/Constructor X in Class Y Cannot be Applied to Given Types in Java, Rollbar Editorial Team. [Online]. Available: https://rollbar.com/blog/how-to-fix-method-constructor-in-class-cannot-be-applied-to-given-types-in-java/. [Accessed: Dec. 21, 2021]

[5] W3schools.com, 2021. Java Type Casting. Refsnes Data. [Online]. Available: https://www.w3schools.com/java/java_type_casting.asp. [Accessed: Dec. 21, 2021]

[6] Oracle.com, 2021. Lesson: Implementations (The Java™ Tutorials > Collections). [Online]. Available: https://docs.oracle.com/javase/tutorial/collections/implementations/index.html. [Accessed: Dec. 21, 2021]

[7] Oracle.com, 2020. Package java.awt (Java SE 15 & JDK 15). Oracle and/or its affiliates [Online]. Available: https://docs.oracle.com/en/java/javase/15/docs/api/java.desktop/java/awt/package-summary.html. [Accessed: Dec. 21, 2021]

Using Kotlin.

I have defined in my root XML data class an element an annotated it with @element

...
  @Element
  var synchronization: Synchronization?,
...

also I have defined a data class Synchronization

@Xml
data class Synchronization(
  @Attribute
  var type: String?,

  @Attribute
  var autosync: Int?,

  @Attribute
  var revision: String?,

  @PropertyElement
  var url: String?,

  @PropertyElement
  var download: String?,

  @PropertyElement
  var upload: String
)

When Android Studio now compiles everything to send it to the device I get following error:

error: incompatible types: Object cannot be converted to Synchronization
Incompatible types. Required: xxx.Synchronization Found: java.lang.Object

In the TypeAdapter of the main XML file there is following code generated and it looks like there is no cast to Synchronization object like in a list.

    childElementBinders.put("synchronization", new ChildElementBinder<ValueHolder>() {
      @Override
      public void fromXml(XmlReader reader, TikXmlConfig config, ValueHolder value) throws
          IOException {
        value.synchronization = config.getTypeAdapter(Synchronization.class).fromXml(reader, config);
      }
    });

For example a list has the needed cast to an account class:

    childElementBinders.put("account", new ChildElementBinder<ValueHolder>() {
      @Override
      public void fromXml(XmlReader reader, TikXmlConfig config, ValueHolder value) throws
          IOException {
        if (value.accounts == null) {
          value.accounts = new ArrayList<Account>();
        }
        value.accounts.add((Account) config.getTypeAdapter(Account.class).fromXml(reader, config) );
      }
    });

Is this a bug or did I miss something?

Код из HeadFirst
Выглядит это так:
/DotComBust.java:5: error: cannot find symbol
private GameHelper helper = GameHelper();//нужные переменные
^
symbol: method GameHelper()
location: class DotComBust
/DotComBust.java:19: error: incompatible types: Object cannot be converted to DotCom
for (DotCom dotComToSet:dotComList){//повторяем с каждым dotcom
^
/DotComBust.java:35: error: incompatible types: Object cannot be converted to DotCom
for (DotCom dotComToTest : dotComList){//сделать это для всех dotcom в списке
^
Note: /DotComBust.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
3 errors

import java.io.*;
import java.util.ArrayList;
import java.util.*;
public class DotComBust{
    private GameHelper helper = GameHelper();//нужные переменные
    private ArrayList dotComList = new ArrayList();//ArrayList только для сайтов
    private int numOfGuesses = 0;
    private void setUpGame(){//создаем сайты и даем им имена
        DotCom one = new DotCom();
        one.setName("Pets.com");
        DotCom two = new DotCom();
        two.setName("eToys.com");
        DotCom three = new DotCom();
        three.setName("Go2.com");
        dotComList.add(one);//помещаем их в ArrayList
        dotComList.add(two);
        dotComList.add(three);
        System.out.println("Потопить 3");//инструкции
        for (DotCom dotComToSet:dotComList){//повторяем с каждым dotcom
            ArrayList<String> newLocation = helper.placeDotCom(3);//зарпашиваем у объекта адрес сайта
            dotComToSet.setLocationCells(newLocation);//вызываем сеттер из dotcom
        }//и передаем ему местоположение корабля, которое
    }//только что получили от другого объекта
    private void startPlaying(){
       while(!dotComList.isEmpty()){ //делать это(далее), пока dotcom не опустеет
           String userGuess = helper.getUserInput("Сделайте ход"); //ход пользователя
           checkUserGuess(userGuess); //проверяем на факт попадания
       }
       finishGame();
    }

    private void checkUserGuess(String userGuess){
        numOfGuesses++;//плюс попытка
        String result = "Мимо";//изначально это мимо
        for (DotCom dotComToTest : dotComList){//сделать это для всех dotcom в списке
            result = dotComToTest.checkYourself(userGuess);//проверяем было ли попадание
            if(result.equals("Попал")){//если да, то...
                break;//останавливаем цикл и ждем следующий ход
            }
            if(result.equals("Потопил")){
                dotComList.remove(dotComToTest);//если потоплен, то удаляем
                break;//из списка и останавливаем цикл
            }
        }
        System.out.println(result);//результат выстрела
    }
    private void finishGame(){
        System.out.println("Все сайты на дне, упс");
        if(numOfGuesses <= 18){
            System.out.println("Отлично " + numOfGuesses);//итог всей игры
        } else {
            System.out.println("Плохо " + numOfGuesses);
        }
    }
    public static void main(String[] args){
        DotComBust game = new DotComBust();//создаем игровой объект
        game.setUpGame();//объявляем подготавливаем игру
        game.startPlaying();//начинаем игру
    }
}
class DotCom{
    private ArrayList<String> locationCells;//местоположение
    private String name;//имя сайта
    public void setLocationCells(ArrayList<String> loc){//обновляет местоположение
        locationCells = loc;//сайта, полученый случайно из placeDotCom()
    }
    public void setName(String n){//"Ваш простой сеттер"
        name = n;
    }
    public String checkYourself(String userInput){
        String result = "Мимо";//если есть попадание, то indexOf вернет его местоположение
        int index = locationCells.indexOf(userInput);//если мимо, то вернет -1
        if (index >= 0){//если попал, то удаляем ячейку по индексу
            locationCells.remove(index);
            if (locationCells.isEmpty()){//если сайт "пуст", то потопил
                result = "Потопил";
                System.out.println("Потоплен " + name);//поздравление
            }else{
                result = "Попал";
            }
        }
        return result;
    }
}
class GameHelper{
    private static final String alphabet = "abcdefg";
    private int gridLength = 7;
    private int gridSize = 49;
    private int [] grid = new int[gridSize];
    private int comCount = 0;
    public String getUserInput(String prompt){
        String inputLine = null;
        System.out.print(prompt + " ");
        try{
            BufferedReader is = new BufferedReader(new InputStreamReader(System.in));
            inputLine = is.readLine();
            if(inputLine.length() == 0) return null;
        }catch(IOException e){
            System.out.println("IOException: " + e);
        }
        return inputLine.toLowerCase();
    }
    public ArrayList<String> placeDotCom(int comSize){
        ArrayList<String> alphaCells = new ArrayList<String>();
        String [] alphacoords = new String [comSize];
        String temp = null;
        int [] coords = new int[comSize];
        int attempts = 0;
        boolean success = false;
        int location = 0;
        comCount++;
        int incr = 1;
        if((comCount % 2) == 1){
            incr = gridLength;
        } 
        while (!success & attempts++ < 200){
            location = (int)(Math.random()*gridSize);
            System.out.print("пробуем " + location);
            int x = 0;
            success = true;
            while (success && x < comSize){
                if(grid[location] == 0){
                    coords[x++] = location;
                    location += incr;
                    if(location >= gridSize){
                        success = false;
                    }
                    if(x>0 && (location % gridLength == 0)){
                        success = false;
                    }
                } else {
                    System.out.print(" используется " + location);
                    success = false;
                }
            }
        }
        int x = 0;
        int row = 0;
        int column = 0;
        while (x < comSize){
        grid[coords[x]] = 1;
        row = (int)(coords[x]/gridLength);
        column = coords[x]%gridLength;
        temp = String.valueOf(alphabet.charAt(column));
        alphaCells.add(temp.concat(Integer.toString(row)));
        x++;
        System.out.print(" coord " + x + alphaCells.get(x-1));
        }
    
   
   return alphaCells;
    }
    
}

Не ругайтесь, я же чайник, мне можно ошибаться

error: incompatible types: java.lang.Object cannot be converted to com.javarush.task.task09.task0927.Solution.Cat

В коде есть метод convertMapToSet(Map<String, Cat> map) .
С него я хочу витянуть обьет Cat , но видает ошибку. — Cat r1 = entry.getValue() ;
Ну а если я буду обьявлять єтот обьект через родительский клас то ошибки не видает — Object r = entry.getValue() ;

Ну и потом я не могу обьет типа Object вставить в свой сет обьектов класа Cat .
Почему когда я вытаскиваю обьект с сета он не может остаться екземпляров класса Cat , а становится сразу екземпляром класса Object ?

package com.javarush.task.task09.task0927;

import java.util.Map;
import java.util.*;

/*
Десять котов
*/

public class Solution {
public static void main(String[] args) {
Map<String, Cat> map = createMap();
Set<Cat> set = convertMapToSet(map);
printCatSet(set);
}

public static Map<String, Cat> createMap() {
//напишите тут ваш код
Map<String, Cat> a = new HashMap<>();
a.put(«Valera1»,new Cat(«Valera»));
return a;
}

public static Set<Cat> convertMapToSet(Map<String, Cat> map) {
//напишите тут ваш код
Set<Cat> a = new HashSet<>();
for (Map.Entry entry : map.entrySet()) {
// a.add(entry.getValue() );
Object r = entry.getValue() ;
Cat r1 = entry.getValue() ;
// System.out.println ( «»+ entry.getKey() );
// a.add(r);
a.add(new Cat(«Valera3») );
}
return a ;
}

public static void printCatSet(Set<Cat> set) {
for (Cat cat : set) {
System.out.println(cat);
}
}

public static class Cat {
private String name;

public Cat(String name) {
this.name = name;
}

public String toString() {
return «Cat » + this.name;
}
}

}

Этот веб-сайт использует данные cookie, чтобы настроить персонально под вас работу сервиса. Используя веб-сайт, вы даете согласие на применение данных cookie. Больше подробностей — в нашем Пользовательском соглашении.

Typecasting is one of the most important concepts which basically deals with the conversion of one data type to another datatype implicitly or explicitly. In this article, the concept of downcasting for objects is discussed. It’s putting the parent’s reference variable holding the child’s object to the child’s reference variable. Downcasting cannot be implicit. The syntax of downcasting is:

Type_A ref1 = new Type_B();
Type_C ref2 = (Type_D) ref1;

In this statement, two operations are performed:

  1. converting an object referred by ref1 to type D
  2. assigning this converted object of type D to a reference variable of type C

There are 3 rules which are checked if the downcasting will be successful or not. The rules are as discussed below:

1. Check for valid conversion

For the conversion to be valid, Type A and Type D must have a relation between them. This relation can be either type A is the parent of type D, or type D is the parent of type A or type A = type D.  If there is no such relation, then there will be a compile-time error. This rule is checked by the compiler and hence it doesn’t consider the type of object created in ref1 i.e it only considers type A and type D, not type B (which is the actual type of runtime object created). Considering this rule, let’s see some statements which satisfy the criteria.

Object ref1 = new String();
String ref2 = (String) ref1; // satisfy rule 1
ref1 is of Object type which is parent of String

Object ref1 = new String();
Integer ref2 = (Integer) ref1 ; // satisfy rule 1
ref1 is of Object type which is parent of Integer

String ref1 = new String();
String ref2 = (String) ref1 ; // satisfy rule 1
ref1 is of String type which is same

String ref1 = new String();
String ref2 = (Object) ref1 ; // satisfy rule 1
ref1 is of String type which is child of Object 

String ref1 = new String();
String ref2 = (Integer) ref1; // doesn't satisfy rule 1
ref1 is of String type which is not related to Integer 
Error: incompatible types: String cannot be converted to Integer

2. Check for a valid assignment

After downcasting, the type of the object will be typed D. We know that an object can be referred to by either the same type or its parent. This leads to the second rule that the type of ref2, type C must be a parent or the same as type D. If this rule is not satisfied then the compiler will throw an error. Considering this rule, let’s see some statements which satisfy the criteria.

Object ref1 = new String();
Object ref2 = (String) ref1 ; // satisfy rule 1 & rule 2
downcasted object of String type is referred by parent type Object

Object ref1 = new String();
Integer ref2 = (Integer) ref1; // satisfy rule 1 & rule 2
downcasted object of Integer type is referred by same type

Object ref1 = new String();
String ref2 = (Object) ref1; // satisfy rule 1 but not rule 2
downcasted object of Object type is referred by child class type String
Error: incompatible types: Object cannot be converted to String

String ref1 = new String();
Integer ref2 = (Integer) ref1; // doesn't satisfy rule 1 & rule 2
downcasted object of Integer type is referred by unrelated class type String
Error: incompatible types: String cannot be converted to Integer

3. Check the Compatibility of the runtime type of object

If we notice the above two points, they cover only the reference types and the converted type. The actual runtime type of the object we are trying to downcast is not yet taken into consideration. This runtime type will now be considered by JVM to check for validity. The child class object can be cast to the same class or parent class. This leads to the third runtime rule which is that type D must be a parent or same as of runtime type of ref1 i.e type B. If this condition fails, the JVM will throw ClassCastException at runtime. Considering this rule, let’s see some statements which satisfy the criteria.

Object ref1 = new String();
Object ref2 = (String) ref1 ; // satisfy rule 1, rul2  & rule 3
downcasted object of String type is same as runtime type String

Object ref1 = new Integer();
Object ref2 = (Number) ref1 ; // satisfy rule 1, rul2  & rule 3
downcasted object of Number type is same parent of runtime type Integer

Object ref1 = new String();
Integer ref2 = (Integer) ref1; // satisfy rule 1, rule 2 but not rule 3
downcasted object of Integer type is not same or parent of runtime type String
Exception in thread "main" java.lang.ClassCastException: class java.lang.String cannot be cast to class java.lang.Integer

I have defined 3 labels in a FXML file within a grid pane. I am trying to read the following XML file and display the labels present in the file in a grid pane. The numerical values in the XML file denotes the row & column position.

<data>
<lbl1>0,0</lbl1>
<lbl2>0,1</lbl2>
<lbl3>0,2</lbl3>
</data>

I have added all the elements to the HashMap and then retrieve it to be displayed. Firstly, I added all the three labels one by one as follows:

hm.put("lbl1", eElement.getElementsByTagName("lbl1").item(0).getTextContent());
hm.put("lbl2", eElement.getElementsByTagName("lbl2").item(0).getTextContent());
hm.put("lbl3", eElement.getElementsByTagName("lbl3").item(0).getTextContent());

Then I display them as follows:

grid.add(lbl1, Integer.parseInt(hm.get("lbl1").toString().split(",")[0]),Integer.parseInt(hm.get("lbl1").toString().split(",")[1]));
grid.add(lbl2, Integer.parseInt(hm.get("lbl2").toString().split(",")[0]),Integer.parseInt(hm.get("lbl2").toString().split(",")[1]));
grid.add(lbl3, Integer.parseInt(hm.get("lbl3").toString().split(",")[0]),Integer.parseInt(hm.get("lbl3").toString().split(",")[1]));

The above code works well without any issues and I can see the labels on the grid.

Now, instead of adding the labels one by one, I added all of them in a single statement through a ‘for’ loop as shown below:

if (!eElement.getTagName().toString().equals("data"))
            hm.put(eElement.getTagName(), eElement.getTextContent());

If I try to display the label, for example:

grid.add(hm.get("lbl1"),0,0);

I get an error:incompatible types — Object cannot be converted to Node.

If I try to typecast:

grid.add((javafx.scene.Node) hm.get("lbl1"),0,0);

I get an error:java.lang.ClassCastException: java.lang.String cannot be cast to javafx.scene.Node

If I print the hashmap entries, the following output is shown:

lbl1=0,0, lbl2=0,1, lbl3=0,2

How to fix this error? Is there any other way in which I can add all the elements in a single statement and then display them?


From your sample code, I guess that hm is an instance of Map<String, String>

So, when you call hm.get("lbl1") , you get a String.

You’re trying to add this String to a GridPane, but the add() method is expecting a javafx.scene.Node. That’s why you get a an error «incompatible types».

Instead, you should add your instances of javafx.scene.control.Label (lbl1, lbl2, lbl3)

Symptoms

Compilation of Java 8 code instrumented by Clover fails when a lambda expression is passed as an argument of a generic method.

Example #1 — overloaded generic methods

For the following code

public class LambdaAndGenerics {
    static interface Predicate<T> {
        boolean test(T t);
    }

    static class Fails {
        void start() {
            System.out.println(goo(e -> false)); // COMPILER ERRORS "reference to goo is ambiguous" + "cannot infer type variables"
        }
        <N> String goo(Class<N> arg) {
            return "Fails class: " + arg;
        }
        <M> String goo(Predicate<M> arg) {
            return "Fails predicate: " + arg.test(null);
        }
    }
    public static void main(String[] args) {
        new Fails().start();
    }
}

compiler fails with:

java: reference to goo is ambiguous
  both method <N>goo(java.lang.Class<N>) in LambdaAndGenerics.Fails and method <M>goo(LambdaAndGenerics.Predicate<M>) in LambdaAndGenerics.Fails match

java: incompatible types: cannot infer type-variable(s) I,T
    (argument mismatch; java.lang.Class is not a functional interface)

Example #2 — Java 8 streams

The following code:

public static List<String> testMapAndCollectBounds(List<String> input) {
    return input.stream()
            .map(e -> e.toUpperCase())
            .collect(Collectors.toList());
}

fails with a compilation error:

incompatible types: inference variable T has incompatible bounds
equality constraints: java.lang.String
lower bounds: java.lang.Object

The following code:

public static Stream<String> testMapAndFilterBounds(List<String> input) {
    return input.stream()
            .map(e -> e.toUpperCase())
            .filter(e -> !e.isEmpty());
}

fails with a compilation error:

incompatible types: java.util.stream.Stream<java.lang.Object> cannot be converted to java.util.stream.Stream<java.lang.String>

Cause

In case of example #1 it’s a bug (aka technical limitation) in Oracle’s javac compiler which fails to perform type inference for several nested generic types or methods. Roughly speaking, due to performance reasons, a compiler performs simplified method matching:

  • in a first step it tries to match all methods with a given name, no matter of their signature to the lambda expression (i.e. it ignores overloading)
  • in a second step it selects a method which fits the best (i.e. taking the one with the most narrow type)

In means that a compiler fails if you have two (or more) overloaded methods and one (or more) of them does have a functional interface argument, while others don’t have.

In case of example #2 this relates with a fact how type of a lambda expression or type of a method reference are being resolved by the compiler. See Java Language Specification, chapters «15.13 Method Reference Expressions» and «15.27 Lambda Expressions» for more details. Due to a fact that an original lambda is being wrapped into Clover’s helper method having a signature like this:

<I, T extends I> I lambdaInc(int index, T lambda, int stmtIndex)

this may cause problems when used with generic method having wildcards, such as:

stream()
    .map(...)       // <R> Stream<R> map(Function<? super T, ? extends R> mapper)
    .collect(...)   // <R> R collect(Supplier<R> supplier, BiConsumer<R, ? super T> accumulator, BiConsumer<R, R> combiner)

Resolution

1) Change a lambda function from an expression to a code block, e.g.:

// expression lambda
System.out.println(goo(e -> false));
// block lambda
System.out.println(goo(e -> { return false; }));

Clover uses different instrumentation for these two lambda forms, so a type inference error will not occur for a lambda block.

2) Or disable instrumentation of lambda functions declared as expressions (since Clover 3.2.2).

Use instrumentLambda = «all_but_reference», «block» or «none»

Ant — build.xml

 <clover-setup instrumentLambda="block"/>

Maven — pom.xml

<configuration>
   <instrumentLambda>block</instrumentLambda>
</configuration>

Grails — BuildConfig.groovy

clover {
   instrumentLambda = "block"
} 

Eclipse:

Open «Project Properties «> «Clover» page > «Instrumentation» tab. In the «Miscellaneous» box select proper value in «Instrument lambda functions» drop-down.

IntelliJ IDEA:

Open «File» > «Settings» > «Project Settings» > «Clover» page > «Compilation» tab. In the «Miscellaneous» box select proper value in «Instrument lambda functions» drop-down. 

3) Or surround a lambda by ///CLOVER:OFF and ///CLOVER:ON comments, e.g.:

... some code ...
///CLOVER:OFF
System.out.println(goo(e -> false));
///CLOVER:ON 
... some code ...

4) Or rename a method which does not have an argument of functional interface type (example #1), e.g.:

static class Works {
    void start() {
        System.out.println(goo(e -> false));
    }
    <M> String goo(Predicate<M> arg) {
        return "goo: " + arg.test(null);
    }
    <M> String goo(SomeFunctionalInterface<M> arg) {
        return "goo: " + arg.run(null);
    }
    <N> String notAGoo(Class<N> arg) { // this is not a functional interface
       return "Class: " + arg;
    }
}

5) Since Clover 4.0.5 heuristics are applied to rewrite lambda expressions in JDK Stream’s and Guava classes’ methods into a block form. More details here: Lambda rewriting heuristics. Try upgrading to Clover 4.0.5 and/or use instrumentLambda="expression" or instrumentLambda="all_but_references".

Bug tracker


CLOV-1465

Getting issue details…
STATUS


CLOV-1596

Getting issue details…
STATUS


CLOV-1762

Getting issue details…
STATUS

I tried converting an ArrayList to an array of strings (String []) and got this error:

java: incompatible types: java.lang.Object[] cannot be converted to java.lang.String[]

My code: 

import java.util.ArrayList;
import java.util.List;

public class Main {

    public static void main(String[] args) {
        List<String> arrayList = new ArrayList<>();
        arrayList.add("x");
        arrayList.add("y");

        String[] strings = arrayList.toArray();  // this line throw an error 
    }
}

I found a solution — It needs to change

String[] strings = arrayList.toArray(); 

to

String[] text = arrayList.toArray(String[]::new)

I also wrote an article about it — Java — convert ArrayList to array[].

Понравилась статья? Поделить с друзьями:
  • Error incompatible types in assignment
  • Error incompatible types got single expected smallint
  • Error incompatible types got real expected smallint
  • Error incompatible types got extended expected smallint
  • Error incompatible types got extended expected longint