Error incompatible types possible lossy conversion from double to int

So I have recently written the following code: import java.util.Scanner; public class TrainTicket { public static void main (String args[]) { Scanner money = new Sca...

When you convert double to int, the precision of the value is lost. For example, when you convert 4.8657 (double) to int, the int value will be 4. Primitive int does not store decimal numbers, so you will lose 0.8657.

In your case, 0.7 is a double value (floating point treated as double by default unless mentioned as float — 0.7f). When you calculate price*much*0.7, the answer is a double value and so the compiler wouldn’t allow you to store it in a type integer since there could be a loss of precision. That’s what is «possible lossy conversion», you may lose precision.

So what could you do about it? You need to tell the compiler that you really want to do it. You need to tell it that you know what you are doing. So explicitly convert double to int using the following code:

int total2= (int) price*much*0.7;
 /*(int) tells compiler that you are aware of what you are doing.*/
 //also called as type casting

In your case,since you are calculating the cost, I’ll suggest you to declare variable total2 as the type double or float.

double total2=price*much*0.7;
 float total2=price*much*0.7;
 //will work

1. Overview

In this quick tutorial, we’ll discuss the concept of lossy conversion in Java and the reason behind it.

At the same time, we’ll explore some handy conversion techniques to avoid this error.

Lossy conversion is simply the loss of information while handling data.

In Java, it corresponds to the possibility of losing the value or precision of a variable while converting one type to another.

When we try to assign a variable of large-sized type to a smaller sized type, Java will generate an error, incompatible types: possible lossy conversion, while compiling the code.

For example, let’s try to assign a long to an int:

long longNum = 10;
int intNum = longNum;

Java will emit an error while compiling this code:

incompatible types: possible lossy conversion from long to int

Here, Java will find long and int incompatible and result in lossy conversion error. Because there can be long values outside the int range -2,147,483,648 to 2,147,483,647.

Similarly, let’s try to assign a float to a long:

float floatNum = 10.12f;
long longNum = floatNum;
incompatible types: possible lossy conversion from float to long

As float can have decimal values that don’t have corresponding long value. Therefore, we’ll receive the same error.

Similarly, assigning a double number to an int will cause the same error:

double doubleNum = 1.2;
int intNum = doubleNum;
incompatible types: possible lossy conversion from double to int

The double values can be too large or too small for an int and decimal values will get lost in the conversion. Hence, it is a potential lossy conversion.

Also, we can run into this error while performing a simple calculation:

int fahrenheit = 100;
int celcius = (fahrenheit - 32) * 5.0 / 9.0;

When a double multiply with an int, we get the result in a double. Consequently, it is also a potential lossy conversion.

Therefore, the incompatible types in lossy conversion can either have different sizes or types (integers or decimals).

3. Primitive Data Types

In Java, there are many primitive data types available with their corresponding wrapper classes.

Next, let’s compile a handy list of all possible lossy conversions in Java:

  • short to byte or char
  • char to byte or short
  • int to byte, short or char
  • long to byte, short, char or int
  • float to byte, short, char, int or long
  • double to byte, short, char, int, long or float

Note that though short and char have the same size. Still, the conversion from short to char is lossy because char is an unsigned data type.

4. Conversion Techniques

4.1. Converting Between Primitive Types

The easy way of converting primitives to avoid lossy conversion is through downcasting; in other words, casting the larger-sized type to a smaller-sized type. Hence, it is also called narrowing primitive conversion.

For instance, let’s convert a long number to a short using downcasting:

long longNum = 24;
short shortNum = (short) longNum;
assertEquals(24, shortNum);

Similarly, let’s convert a double to an int:

double doubleNum = 15.6;
int integerNum = (int) doubleNum;
assertEquals(15, integerNum);

However, we should note that converting large-sized type with values too large or too small to smaller-sized type through downcasting can result in unexpected values.

Let’s convert long values outside the range of short:

long largeLongNum = 32768; 
short minShortNum = (short) largeLongNum;
assertEquals(-32768, minShortNum);

long smallLongNum = -32769;
short maxShortNum = (short) smallLongNum;
assertEquals(32767, maxShortNum);

If we carefully analyze the conversion, we’ll see that these are not the expected values.

In other words, when Java hits the highest value of a small-sized type while converting from large-sized type, the next number is the lowest value of the small-sized type and vice-versa.

Let’s understand this through examples. When largeLongNum with the value of 32768 is converted to short, the value of shortNum1 is -32768. Because the max value of short is 32767, therefore, Java goes for the next min value of the short.

Similarly, when smallLongNum is converted to short. The value of shortNum2 is 32767 as Java goes for the next max value of the short.

Also, let’s see what happens when we convert the max and min values of a long to an int:

long maxLong = Long.MAX_VALUE; 
int minInt = (int) maxLong;
assertEquals(-1, minInt);

long minLong = Long.MIN_VALUE;
int maxInt = (int) minLong;
assertEquals(0, maxInt);

4.2. Converting Between Wrapper Objects and Primitive Types

To directly convert a wrapper object to a primitive, we can use various methods in wrapper classes such as intValue(), shortValue() and longValue(). This is called unboxing.

For instance, let’s convert a Float object to a long:

Float floatNum = 17.564f;
long longNum = floatNum.longValue();
assertEquals(17, longNum);

Also, if we look at the implementation of longValue or similar methods, we’ll find the use of narrowing primitive conversion:

public long longValue() {
    return (long) value;
}

However, at times, narrowing primitive conversion should be avoided to save valuable information:

Double doubleNum = 15.9999;
long longNum = doubleNum.longValue();
assertEquals(15, longNum);

After conversion, the value of longNum will be 15. However, the doubleNum is 15.9999, which is very close to 16.

Instead, we can use Math.round() for conversion to the closest integer:

Double doubleNum = 15.9999;
long longNum = Math.round(doubleNum);

assertEquals(16, longNum);

4.3. Converting Between Wrapper Objects

For this, let’s use the already discussed conversion techniques.

First, we’ll convert wrapper object to a primitive value, downcast it and convert it to another wrapper object. In other words, we’ll perform unboxing, downcasting, and boxing techniques.

For example, let’s convert a Double object to an Integer object:

Double doubleNum = 10.3;
double dbl = doubleNum.doubleValue(); // unboxing
int intgr = (int) dbl; // downcasting
Integer intNum = Integer.valueOf(intgr);
assertEquals(Integer.valueOf(10), intNum);

Lastly, we’re using Integer.valueOf() to convert the primitive type int to an Integer object. This type of conversion is called boxing.

5. Conclusion

In this article, we’ve explored the concept of lossy conversion in Java with the help of a number of examples. In addition, we’ve compiled a handy list of all possible lossy conversions as well.

Along the way, we’ve identified narrowing primitive conversion as an easy technique to convert primitive numbers and avoid the lossy conversion error.

At the same time, we’ve also explored additional handy techniques for numeric conversions in Java.

The code implementations for this article can be found over on GitHub.

Содержание

  1. How to Handle the Incompatible Types Error in Java
  2. Introduction to Data Types & Type Conversion
  3. Incompatible Types Error: What, Why & How?
  4. Incompatible Types Error Examples
  5. Explicit type casting
  6. getting error: incompatible types: possible lossy conversion from double to int

How to Handle the Incompatible Types Error in Java

Table of Contents

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.

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].

Источник

getting error: incompatible types: possible lossy conversion from double to int

  • Hello all, I’m getting errors on my Java. I’m not understanding what the error means. How do I fix them?

    Create an abstract class called Shape to store information about a shape. Each shape contains the figure type and a method to calculate the area. Create sub-classes of Shape called Square and Circle. Note: That radius, sides, and areas can be decimals.

    ShapeMain.java
    Shape.java
    Square.java
    Circle.java

    Shape Main Class

    Use the main class for testing. You won’t be graded on your main class other than it must exist.

    Build the Shape class with the following specifications:

    Must be abstract
    Public abstract getArea()

    Build the Square class with the following specifications:

    Subclass of Shape
    Public setSide()
    Public getSide()
    Implements getArea() correctly

    Ex: Using setSide(5) results in getArea() return 10. Area = side*side

    Build the Circle class with the following specifications:

    Subclass of Shape
    Public setRadius()
    Public getRadius()
    Implements getArea() correctly

    Ex: Using setRadius(5) results in getArea() return 10. Area = PI*(R^2). Hint use Math.PI

    Here is my code:

  • Thank you guys, I adjusted the int to a double. The only trouble I have now is for this Test, «Circle setRadius & getArea.»
    It shows my output as: Circle setRadius & getArea not implemented correctly.
    Do you see a reason that it is giving me this? It is not an error in Java, it is just a portion of the test that is not correct.
    Do I not have my math formula correct for the radius? (Circle class. Line 23)

  • All things are lawful, but not all things are profitable.

  • Hi guys, thanks for responding. The assignment is from ZyBooks, an online class, that is very strict about how code and spacing is written. The used items come from the lesson. (see below)
    Sorry about the color, I just want to emphasize the wording for the examples. I have found throughout the class, that the examples are the information ZyBooks wants used. So that is why I used what I did.
    I know that there has to be better ways of doing this, but since this is my first Java class, I am just barely beginning. I hope I addressed why my code is written like this. Please if there is something I can change that will help me it would be well received and I would be thankful for your help and advice.

    Build the Square class with the following specifications:
    Subclass of Shape
    Public setSide()
    Public getSide()
    Implements getArea() correctly

    Ex: Using setSide(5) results in getArea() return 10. Area = side*side

    Circle Class
    Build the Circle class with the following specifications:
    Subclass of Shape
    Public setRadius()
    Public getRadius()
    Implements getArea() correctly

    Источник

    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]

    Автор оригинала: baeldung.

    1. Обзор

    В этом кратком руководстве мы обсудим концепцию преобразования с потерями в Java и причину этого.

    В то же время мы рассмотрим некоторые удобные методы преобразования, чтобы избежать этой ошибки.

    2. Преобразование С Потерями

    Преобразование с потерями-это просто потеря информации при обработке данных.

    В Java это соответствует возможности потери значения или точности переменной при преобразовании одного типа в другой.

    Когда мы пытаемся назначить переменную типа большого размера типу меньшего размера , Java генерирует ошибку, несовместимые типы: возможное преобразование с потерями , при компиляции кода.

    Например, давайте попробуем назначить long для int :

    long longNum = 10;
    int intNum = longNum;

    Java выдаст ошибку при компиляции этого кода:

    incompatible types: possible lossy conversion from long to int

    Здесь Java найдет long и int несовместимыми и приведет к ошибке преобразования с потерями. Потому что могут быть длинные значения за пределами int диапазона от -2,147,483,648 до 2,147,483,647.

    Аналогично, давайте попробуем назначить float a long :

    float floatNum = 10.12f;
    long longNum = floatNum;
    incompatible types: possible lossy conversion from float to long

    Поскольку float может иметь десятичные значения, которые не имеют соответствующего long значения. Поэтому мы получим ту же ошибку.

    Аналогично, присвоение double номера int приведет к той же ошибке:

    double doubleNum = 1.2;
    int intNum = doubleNum;
    incompatible types: possible lossy conversion from double to int

    Значения double могут быть слишком большими или слишком маленькими для int , и десятичные значения будут потеряны при преобразовании. Следовательно, это потенциальное преобразование с потерями.

    Кроме того, мы можем столкнуться с этой ошибкой при выполнении простого вычисления:

    int fahrenheit = 100;
    int celcius = (fahrenheit - 32) * 5.0 / 9.0;

    Когда double умножается на int , мы получаем результат в double . Следовательно, это также потенциальное преобразование с потерями.

    Поэтому несовместимые типы в преобразовании с потерями могут иметь разные размеры или типы (целые или десятичные числа).

    3. Примитивные Типы данных

    В Java существует множество примитивных типов данных, доступных с соответствующими классами-оболочками .

    Далее давайте составим удобный список всех возможных преобразований с потерями в Java:

    • short to byte или char
    • char to байт или короткий
    • int to byte , short или char
    • long to byte , short , char или int
    • float to byte , short , char , int или long
    • double to byte , short , char , int , long или float

    Обратите внимание, что хотя short и char имеют одинаковый размер. Тем не менее, преобразование из short в char приводит к потерям, поскольку char является типом данных без знака .

    4. Методы преобразования

    4.1. Преобразование Между Примитивными Типами

    Простой способ преобразования примитивов, чтобы избежать преобразования с потерями,-это понижение; другими словами, приведение типа большего размера к типу меньшего размера. Следовательно, это также называется сужением примитивного преобразования.

    Например, давайте преобразуем длинное число в короткое с помощью понижающей передачи :

    long longNum = 24;
    short shortNum = (short) longNum;
    assertEquals(24, shortNum);

    Аналогично, давайте преобразуем double в int :

    double doubleNum = 15.6;
    int integerNum = (int) doubleNum;
    assertEquals(15, integerNum);

    Однако следует отметить, что преобразование типа большого размера со слишком большими или слишком маленькими значениями в тип меньшего размера с помощью понижения может привести к неожиданным значениям.

    Давайте преобразуем длинные значения за пределами диапазона короткие :

    long largeLongNum = 32768; 
    short minShortNum = (short) largeLongNum;
    assertEquals(-32768, minShortNum);
    
    long smallLongNum = -32769;
    short maxShortNum = (short) smallLongNum;
    assertEquals(32767, maxShortNum);

    Если мы внимательно проанализируем конверсию, то увидим, что это не ожидаемые значения.

    Другими словами, когда Java достигает наибольшего значения типа малого размера при преобразовании из типа большого размера, следующее число является наименьшим значением типа малого размера и наоборот.

    Давайте разберемся в этом на примерах. Когда большое длинное число со значением 32768 преобразуется в короткое , значение короткое число 1 равно -32768 . Поскольку максимальное значение short равно 32767, поэтому Java переходит к следующему минимальному значению short.

    Аналогично, когда маленькое длинное число преобразуется в короткое . Значение short Num2 равно 32767, поскольку Java переходит к следующему максимальному значению short .

    Кроме того, давайте посмотрим, что произойдет, когда мы преобразуем максимальные и минимальные значения a long в int :

    long maxLong = Long.MAX_VALUE; 
    int minInt = (int) maxLong;
    assertEquals(-1, minInt);
    
    long minLong = Long.MIN_VALUE;
    int maxInt = (int) minLong;
    assertEquals(0, maxInt);

    4.2. Преобразование между объектами-оболочками и примитивными типами

    Чтобы напрямую преобразовать объект-оболочку в примитив, мы можем использовать различные методы в классах-оболочках, такие как int Value () , shortValue() и longValue() . Это называется распаковка .

    Например, давайте преобразуем объект Float в объект long :

    Float floatNum = 17.564f;
    long longNum = floatNum.longValue();
    assertEquals(17, longNum);

    Кроме того, если мы посмотрим на реализацию long Value или аналогичных методов, мы найдем применение сужающего примитивного преобразования:

    public long longValue() {
        return (long) value;
    }

    Однако иногда следует избегать сужения примитивного преобразования, чтобы сохранить ценную информацию:

    Double doubleNum = 15.9999;
    long longNum = doubleNum.longValue();
    assertEquals(15, longNum);
    

    После преобразования значение long Num будет равно 15. Однако двойное число равно 15.9999, что очень близко к 16.

    Вместо этого мы можем использовать Math.round() для преобразования в ближайшее целое число:

    Double doubleNum = 15.9999;
    long longNum = Math.round(doubleNum);
    
    assertEquals(16, longNum);

    4.3. Преобразование Между Объектами-Оболочками

    Для этого давайте воспользуемся уже рассмотренными методами преобразования.

    Сначала мы преобразуем объект-оболочку в примитивное значение, опустим его и преобразуем в другой объект-оболочку . Другими словами, мы будем выполнять техники распаковки, даункастинга и бокса.

    Например, давайте преобразуем объект Double в объект Integer :

    Double doubleNum = 10.3;
    double dbl = doubleNum.doubleValue(); // unboxing
    int intgr = (int) dbl; // downcasting
    Integer intNum = Integer.valueOf(intgr);
    assertEquals(Integer.valueOf(10), intNum);
    

    Наконец, мы используем Integer . valueOf() для преобразования примитивного типа int в Целое число объект. Этот тип преобразования называется boxing .

    5. Заключение

    В этой статье мы исследовали концепцию преобразования с потерями в Java с помощью ряда примеров. Кроме того, мы также составили удобный список всех возможных конверсий с потерями.

    Попутно мы определили сужение примитивного преобразования как простой метод преобразования примитивных чисел и избежания ошибки преобразования с потерями.

    В то же время мы также изучили дополнительные удобные методы числовых преобразований в Java.

    Реализации кода для этой статьи можно найти на GitHub .

    1. Overview

    In this quick tutorial, we’ll discuss the concept of lossy conversion in Java and the reason behind it.

    At the same time, we’ll explore some handy conversion techniques to avoid this error.

    2. Lossy Conversion

    Lossy conversion is simply the loss of information while handling data.*
    *

    In Java, it corresponds to the possibility of losing the value or precision of a variable while converting one type to another.

    When we try to assign a variable of large-sized type to a smaller sized type, Java will generate an error, incompatible types: possible lossy conversion, while compiling the code.

    For example, let’s try to assign a long to an int:

    long longNum = 10;
    int intNum = longNum;

    Java will emit an error while compiling this code:

    incompatible types: possible lossy conversion from long to int

    Here, Java will find long and int incompatible and result in lossy conversion error. Because there can be long values outside the int range -2,147,483,648 to 2,147,483,647.

    Similarly, let’s try to assign a float to a long:

    float floatNum = 10.12f;
    long longNum = floatNum;
    incompatible types: possible lossy conversion from float to long

    As float can have decimal values that don’t have corresponding long value. Therefore, we’ll receive the same error.

    Similarly, assigning a double number to an int will cause the same error:

    double doubleNum = 1.2;
    int intNum = doubleNum;
    incompatible types: possible lossy conversion from double to int

    The double values can be too large or too small for an int and decimal values will get lost in the conversion. Hence, it is a potential lossy conversion.

    Also, we can run into this error while performing a simple calculation:

    int fahrenheit = 100;
    int celcius = (fahrenheit - 32) * 5.0 / 9.0;

    When a double multiply with an int, we get the result in a double. Consequently, it is also a potential lossy conversion.

    Therefore, the incompatible types in lossy conversion can either have different sizes or types (integers or decimals).*
    *

    3. Primitive Data Types

    Next, let’s compile a handy list of all possible lossy conversions in Java:

    • short to byte or char

    • char to byte or short

    • int to byte, short or char

    • long to byte, short, char or int

    • float to byte, short, char, int or long

    • double to byte, short, char, int, long or float

    Note that though short and char have the same size. Still, the conversion from short to char is lossy because char is an unsigned data type.

    4. Conversion Techniques

    ==== 4.1. Converting Between Primitive Types

    The easy way of converting primitives to avoid lossy conversion is through downcasting; in other words, casting the larger-sized type to a smaller-sized type. Hence, it is also called narrowing primitive conversion.

    For instance, let’s convert a long number to a short using downcasting:

    long longNum = 24;
    short shortNum = (short) longNum;
    assertEquals(24, shortNum);

    Similarly, let’s convert a double to an int:

    double doubleNum = 15.6;
    int integerNum = (int) doubleNum;
    assertEquals(15, integerNum);

    However, we should note that converting large-sized type with values too large or too small to smaller-sized type through downcasting can result in unexpected values.

    Let’s convert long values outside the range of short:

    long largeLongNum = 32768;
    short minShortNum = (short) largeLongNum;
    assertEquals(-32768, minShortNum);
    
    long smallLongNum = -32769;
    short maxShortNum = (short) smallLongNum;
    assertEquals(32767, maxShortNum);

    If we carefully analyze the conversion, we’ll see that these are not the expected values.

    In other words, when Java hits the highest value of a small-sized type while converting from large-sized type, the next number is the lowest value of the small-sized type and vice-versa.

    Let’s understand this through examples. When largeLongNum with the value of 32768 is converted to short, the value of shortNum1 is -32768. Because the max value of short is 32767, therefore, Java goes for the next min value of the short.

    Similarly, when smallLongNum is converted to short. The value of shortNum2 is 32767 as Java goes for the next max value of the short.

    Also, let’s see what happens when we convert the max and min values of a long to an int:

    long maxLong = Long.MAX_VALUE;
    int minInt = (int) maxLong;
    assertEquals(-1, minInt);
    
    long minLong = Long.MIN_VALUE;
    int maxInt = (int) minLong;
    assertEquals(0, maxInt);

    4.2. Converting Between Wrapper Objects and Primitive Types

    To directly convert a wrapper object to a primitive, we can use various methods in wrapper classes such as intValue(), shortValue() and longValue(). This is called unboxing.

    For instance, let’s convert a Float object to a long:

    Float floatNum = 17.564f;
    long longNum = floatNum.longValue();
    assertEquals(17, longNum);

    Also, if we look at the implementation of longValue or similar methods, we’ll find the use of narrowing primitive conversion:

    public long longValue() {
        return (long) value;
    }

    However, at times, narrowing primitive conversion should be avoided to save valuable information:

    Double doubleNum = 15.9999;
    long longNum = doubleNum.longValue();
    assertEquals(15, longNum);

    After conversion, the value of longNum will be 15. However, the doubleNum is 15.9999, which is very close to 16.

    Instead, we can use Math.round() for conversion to the closest integer:

    Double doubleNum = 15.9999;
    long longNum = Math.round(doubleNum);
    
    assertEquals(16, longNum);

    4.3. Converting Between Wrapper Objects

    For this, let’s use the already discussed conversion techniques.

    First, we’ll convert wrapper object to a primitive value, downcast it and convert it to another wrapper object. In other words, we’ll perform unboxing, downcasting, and boxing techniques.

    For example, let’s convert a Double object to an Integer object:

    Double doubleNum = 10.3;
    double dbl = doubleNum.doubleValue(); // unboxing
    int intgr = (int) dbl; // downcasting
    Integer intNum = Integer.valueOf(intgr);
    assertEquals(Integer.valueOf(10), intNum);

    Lastly, we’re using Integer.valueOf() to convert the primitive type int to an Integer object. This type of conversion is called boxing.

    5. Conclusion

    In this article, we’ve explored the concept of lossy conversion in Java with the help of a number of examples. In addition, we’ve compiled a handy list of all possible lossy conversions as well.

    Along the way, we’ve identified narrowing primitive conversion as an easy technique to convert primitive numbers and avoid the lossy conversion error.

    At the same time, we’ve also explored additional handy techniques for numeric conversions in Java.

    The code implementations for this article can be found over on GitHub.


    posted 3 years ago

    • Mark post as helpful


    • send pies

      Number of slices to send:

      Optional ‘thank-you’ note:



    • Quote
    • Report post to moderator

    Hello all, I’m getting errors on my Java. I’m not understanding what the error means. How do I fix them?

                                       

    Problem Description:

    Create an abstract class called Shape to store information about a shape. Each shape contains the figure type and a method to calculate the area. Create sub-classes of Shape called Square and Circle. Note: That radius, sides, and areas can be decimals.

    Files

       ShapeMain.java

       Shape.java

       Square.java

       Circle.java

    Shape Main Class

    Use the main class for testing. You won’t be graded on your main class other than it must exist.

    Shape Class

    Build the Shape class with the following specifications:

       Must be abstract

       Public abstract getArea()

    Square Class

    Build the Square class with the following specifications:

       Subclass of Shape

       Public setSide()

       Public getSide()

       Implements getArea() correctly

    Ex: Using setSide(5) results in getArea() return 10. Area = side*side

    Circle Class

    Build the Circle class with the following specifications:

       Subclass of Shape

       Public setRadius()

       Public getRadius()

       Implements getArea() correctly

    Ex: Using setRadius(5) results in getArea() return 10. Area = PI*(R^2). Hint use Math.PI

    Here is my code:

    Click on the blue words in the upper left corner and follow “Big Guy outside the pot”

    Focus on sharing the latest foreign technology content

    1. An overview of the
    In this quick tutorial, we’ll discuss the concept of lossy transformations in Java and the reasons behind them.
    In the meantime, we’ll explore some convenient transformation techniques to avoid this error.
    2. Lossy conversion
    Lossy transformation is the loss of information while processing data.
    In Java, this corresponds to the possibility of losing variable values or precision when converting from one type to another.
    When we try to convert a variable of a high-level type to a low-level type, Java will generate an incorrect, incompatible type when compiling the code: a potentially lossy conversion.
    For example, let’s try assigning a long value to an int value:

    long longNum = 10;	
    int intNum = longNum;

    When compiling this code, Java produces an error:

    incompatible types: possible lossy conversion from long to int

    Here, Java will find that long and int are incompatible and cause lossy conversion errors. Because you can have long values outside of the int range of -2,147,483,648 to 2,147,483,647.
    Similarly, we try to assign a long to a float:

    float floatNum = 10.12f;	
    long longNum = floatNum;	
    incompatible types: possible lossy conversion from float to long

    Because floats can represent small values that don’t have a corresponding long type. Therefore, we will receive the same error.
    Similarly, converting a double to an int results in the same error:

    double doubleNum = 1.2;	
    int intNum = doubleNum;	
    incompatible types: possible lossy conversion from double to int

    The double value may be too large or too small for an int value, and the small value will be lost in the conversion. Therefore, this is a potentially lossy transformation.
    In addition, we may encounter this error when performing a simple calculation:

    int fahrenheit = 100;	
    int celcius = (fahrenheit - 32) * 5.0/9.0;

    When a double is multiplied by an int, the result is a double. Therefore, it is also a potentially lossy transformation.
    Therefore, incompatible types in lossy conversions can have different sizes or types (integer or decimal).
    3. Basic data types
    In Java, there are many basic data types and their corresponding wrapper classes.
    Next, let’s make a list of all possible lossy transformations in Java:
    short to byte or charchar to byte or shortint to byte, short or charlong to byte, short, char or intfloat to byte, short, char, int or longdouble to byte, short, char, int, long or float
    Note that although short and CHAR have the same range. However, the conversion from short to char is lossy because char is an unsigned data type.
    4. Transform technology
    4.1. Conversion between two basic data types
    The simple way to avoid lossy conversions for primitive types is by casting down; In other words, cast a high-level type to a low-level type. For this reason, it is also called a narrowing primitive conversion.
    For example, let’s convert long to short using a downward cast:

    long longNum = 24;	
    short shortNum = (short) longNum;	
    assertEquals(24, shortNum);

    Similarly, convert a double to an int:

    double doubleNum = 15.6;	
    int integerNum = (int) doubleNum;	
    assertEquals(15, integerNum);

    However, we should note that casting down a high-level type with a value too large or too small to a low-level type can result in unexpected values.
    We convert a long value to a value outside the range of the short type:

    long largeLongNum = 32768; 	
    short minShortNum = (short) largeLongNum;	
    assertEquals(-32768, minShortNum);	
    
    	
    long smallLongNum = -32769;	
    short maxShortNum = (short) smallLongNum;	
    assertEquals(32767, maxShortNum);

    If we look closely at the transformations, we see that these are not the expected values.
    In other words, when Java is converting from a high-level type to a low-level type, when the maximum value of the low-level type is reached, the next value is the minimum value of the low-level type, and vice versa.
    Let’s look at an example to understand this. When largeLongNum with a value of 32768 is converted to short, the value of shortNum1 is -32768. Since the maximum value of short is 32767, Java will select the next minimum value of short.
    Similarly, when smallLongNum is converted to short. ShortNum2 has a value of 32767, which Java USES as the next maximum for Short.
    Also, let’s look at what happens when we convert the maximum and minimum values of long to ints:

    long maxLong = Long.MAX_VALUE; 	
    int minInt = (int) maxLong;	
    assertEquals(-1, minInt);	
    
    	
    long minLong = Long.MIN_VALUE;	
    int maxInt = (int) minLong;	
    assertEquals(0, maxInt);

    4.2. Convert between wrapper objects and primitive types
    To convert the wrapper object directly to the base type, we can use various methods in the wrapper class, such as intValue(), shortValue(), and longValue(). This is called unpacking.
    For example, let’s convert a Float object to a long:

    Float floatNum = 17.564f;	
    long longNum = floatNum.longValue();	
    assertEquals(17, longNum);

    In addition, if we look at the implementation of longValue or similar methods, we will find the use of narrowing the original transformation:

    public long longValue() {	
        return (long) value;	
    }

    However, sometimes you should avoid narrowing the original transformation to preserve valuable information:

    Double doubleNum = 15.9999;	
    long longNum = doubleNum.longValue();	
    assertEquals(15, longNum);

    After conversion, the value of longNum is 15. However, doubleNum is 15.9999, very close to 16.
    Instead, we can use math. round() to convert to the nearest integer:

    Double doubleNum = 15.9999;	
    long longNum = Math.round(doubleNum);	
    assertEquals(16, longNum);

    4.3. Convert between wrapper objects
    To do this, let’s use the transformation techniques we’ve already discussed.
    First, we will convert the wrapper object to a base value, cast it down and convert it to another wrapper object. In other words, we will perform unboxing, downcast, and boxing techniques.
    For example, let’s convert a Double object to an Integer object:

    Double doubleNum = 10.3;	
    double dbl = doubleNum.doubleValue(); // unboxing	
    int intgr = (int) dbl; // downcasting	
    Integer intNum = Integer.valueOf(intgr);	
    assertEquals(Integer.valueOf(10), intNum);

    Finally, we use intet.valueof () to convert the basic type int to an Integer object. This type of conversion is called boxing.
    5. To summarize
    In this article, we explored the concept of lossy transformations in Java through examples. In addition, we have written a handy list of all possible lossy transformations in Java.
    Along the way, we’ve determined that narrowing the original transform is an easy way to transform the base type and avoid lossy conversion errors.
    At the same time, we explored other convenient techniques for numeric conversion in Java.
    The code implementation for this article can be found on the GitHub project.  
    From spring for All community Translation group


    Recently, I have translated the articles into PDF.
    Reply in the background of official account: 002 can get oh ~
    The content of PDF will be updated continuously in the future, please look forward to it!

    ● Top 10 mistakes you make using the Spring Framework
    ● Why Spring as the Java framework?
    ●Solr full-text search
    Top right button to share with more people ~

    Here we are. Click and watch before you go

    Глава №2

    Наконец удалось закончить еще одну статью из моего цикла по изучению Java. Это маленький повод для гордости, что я все же не забросил пока это дело. Так, что всех кому это интересно, милости просим под кат =)

     Данная глава дает преставление о таких вещах как:

    • Что такое простые типы данных
    • Что такое литералы (мое любимое, в кавычках)
    • Как происходит инициализация переменных
    • Область действия переменных
    • Какие арифметические операции можно выполнять над переменными
    • Операции отношения и логические операции
    • Использование круглых скобок
    • Что такое операторы присваивания
    • Как выглядят укороченные операторы присваивания
    • Преобразование типов при присваивании
    • Привидение несовместимых типов данных
    • Преобразование типов в выражениях
    • Список вопросов к самопроверке
    • Домашнее задание
    • Ссылки на примеры и коды программ

    И так приступим =)

    Полностью переписывать главу из книги я не буду, хотя моя супруга иногда говорит, что именно так я и делаю =) Но все же вкратце упомянуть обо всем стоит!

    Что такое простые типы данных.

    Или как их еще называют «примитивные типы данных«, это:

    • byte
    • short
    • int
    • long
    • float
    • double
    • char
    • boolean

    Список типов переменных приведен в порядке увеличения диапазона возможных хранимых в них данных (от меньшего к большему), за исключением двух последних (о них я упомяну отдельно).

    Типы данных от byte до long – это целочисленные типы данных. Учитывая, что язык Java является строго типизированным языком программирования, то это те типы в которых могут содержатся только целые числа (без дробной части). Диапазон допустимых значений у каждой из них свой:

    Тип Разрядность в битах Диапазон допустимых значений
    byte 8 От -128 до 127
    short 16 От -32 768 до 32 767
    int 32 От -214 748 3648 до 214 748 3647
    long 64 От -9 223 372 036 854 775 808 до 9 223 372 036 854 775 807

    Как видно из таблицы в Java числа могут быть как положительными, так и отрицательными. Так, что можно использовать любые числа для переменных, это довольно удобно, но нужно внимательно за этим следить, так как это может вызвать так называемый эффект переполнения типа данных (об этом я напишу чуть позже).

    Размер выделенной памяти (разрядность) для того или иного типа данных может быть каким угодно, а вот диапазон хранимых в ней значений всегда будет одним и тем же. Именно благодаря этому в Java и обеспечивается кроссплатформенность!

    Типы данных float и double – это в которых можно хранить данные с дробной часть (в школе их называли дробями). Размеры выделяемой для них памяти по умолчанию 32 и 64 бита.

    Как я и говорил одним из типов заслуживающих отдельного внимания, является тип char. Данный тип не является чем-то новым, как и в других языках он предназначен для хранения символов. Его отличием являет же возможность записи любого символа любого языка в мире, так называемая кодировка Unicode (не путать с кодировкой отображения символов на экране).

    Присваивается же значение переменной такого типа в следующем формате:

    
    char ch;
    ch = 'a';
    

    Согласно стандарту, его значение вписывается в одинарных кавычках, а не двойных или вообще без них. При попытке скомпилировать программу задав значение без кавычек, выдаст ошибку, что указанный символ не найден в таблице, исключением же будет задание числового значения этой переменной.

    Поэтому этот тип считают целочисленным. Но это только формально и на самом деле если переменной этого типа присвоить значение какого-либо числа, например:

    
    ch = 90;
    

    То при выводе на экран этой переменной, выведется не число 90, а символ «Z» которому соответствует порядковый номер 90 в таблице Unicode, точнее ASCII которая входит в ее состав!

    Если же попытаться задать значение переменной в двойных кавычках, то выдаст ошибку о том, что данных тип не может быть автоматически преобразован в строковый тип данных!

    Можно было бы уделить больше вниманию этой теме, но думаю пока это не нужно.

    Ссылки по теме:

    • Таблица символов Unicode
    • Unicode wiki
    • Unicode 10.0 Character Code Charts

    Следующим типом со своими плюшками является тип boolean, он может содержать только два значения true или false. Но его особенность заключается не в этом, а в том, что он является логическим типом данных!

    Что это значит?!

    А то, что любая операция сравнения или выполнения логического оператора типа if будет содержать в себе булево значение!

    Логический тип данных, или булев тип, или булевый тип (от англ. Boolean или logical data type) — примитивный тип данных в информатике, принимающий два возможных значения, иногда называемых истиной (true) и ложью (false). Присутствует в подавляющем большинстве языков программирования как самостоятельная сущность или реализуется через численный тип данных. В некоторых языках программирования за значение истина полагается 1, за значение ложь — 0.

    Примечание: Из-за значений 0 и 1 не следует его приписывать к целочисленным типам данных, это логический тип данных!

    Литералы

    Об этом я не могу ни сказать =)) ни слова без улыбки. Как говорит одна пословица:

    Шкатулка просто открывалась.

    Об этом загадочном слове много чего пишут, что есть мол шестнадцатеричные литералы, восьмеричные и двоичные! Есть даже строковые литералы!

    Но (драматическая пауза, барабанная дробь и все такое) литералы, это всего лишь значение переменных. Да именно так! Это то значение, которое мы присваиваем переменным =)

    Единственное на, что стоит обратить внимание, так это на то, что строковый литерал – это набор символов, заключенный в двойные кавычки. Например:

    
    System.out.println("Какой-то текст");
    

    Где фраза «Какой-то текст» и будет строковым литералом.

    Последнее, что я здесь добавлю, так это шпаргалку по управляющим последовательностям символов для себя умного =)

    Управляющая последовательность Описание
    Вывод одинарной кавычки
    « Вывод двойной кавычки
    \ Вывод обратной косой черты
    r Возврат каретки
    n Перевод на новую строку
    f Перевод на новую страницу
    t Отступ в виде табуляции
    d Возврат на одну позицию
    ddd Восьмеричная константа, где ddd – восьмеричное число
    uxxxx Шестнадцатиричная константа, где xxxx – шестнадцатиричное число

    Последовательность этих символов очень широко применяется при выводе информации на экран (как можно понять из самой таблицы) для ее форматирования.

    Инициализация переменных.

    1000 и один раз уже говорилось, что Java является языком строго типизированный. Так вот, по мимо задания типа переменных, перед ее использованием нужно ее инициализировать, проще говоря присвоить ей какое-то начальное значение, а уже потом выполнять над ней какие-либо действия!

    Условная форма записи инициализации переменной (по сути она же и операция присваивания значения, о чем немного позже будет упомянуто) выглядит так:

    тип переменная = значение;

    Здесь «значение» и будет той самой точкой инициализации переменной или переменных.

    По мимо такого типа инициализации есть еще «динамическая инициализация«, это когда свое значение переменная получает в результате кокой то операции над числами, символами или другими переменными. Например (динамическая инициализация переменных):

    
    Class DynInit {
        public static void main(String[] args) {
    
            double radius = 4, height = 5;
    
            // Переменная volume инициализируется динамически во время выполнения программы
            double volume = 3.1416 * radius * radius * height;
            
            System.out.println("Объем: " + volume);
        }
    }
    

    Область действия переменных

    Это то место в коде где данная переменная будет выполнять свои функции и хранить в себе какое-то значение. Когда же эта область закончится, то переменная перестанет существовать и будет стерта из памяти, и как уже можно догадаться, посмотреть или получить ее значение будет невозможно! И при попытке это сделать будет выдана ошибка:

    
    Error:(15, 9) java: cannot find symbol
                    symbol:   variable a
    
    location: class com.gmail.vitaliy1984.Test
    

    В котором говорится, что переменной которой присваивается значение не существует!

    Так что же это за такое таинственное место?

    Все довольно просто – это то место в коде, где происходят какие-либо действия с переменными. Ну, например, так:

    
    class ScopeDemo {
        public static void main(String[] args) {
    
            int x; // Эта переменная доступная для всего кода в методе main
            x = 10;
            
            if (x == 10) {  // Начало новой области действия
                int y = 20; // Эта переменная доступна только в даном блоке
    
                //Обе переменные "x" и "y" доступны в данном блоке
                System.out.println("x and y: " + x + " " + y);
                
                x = y * 2;
            }
    
            //y = 100; // Ошибка! В этом месте переменная "y" недоступна
    
            // А переменная "x" по-прежнему доступна
            System.out.println("x is " + x);
        }
    }
    

    Уж если совсем проще говоря, то переменная будет действовать и жить от первой перед ней фигурной скобки «{» и заканчивая такой же ее закрывающей «}«. За их пределами этой переменной просто не существует физически!

    Исходя из этого, если переменная была объявлена к примеру, в начале метода (еще одно страшное слово, но оно уже примелькалось и в книге об этом тоже рассказывается), то повторное ее объявление, например, так:

    
    public class Test {
        public static void main(String[] args) {
            
            int i, a;
    
            for (i = 0; i < 10; i++) {
    
                int a;
                a = 5 + i;
    
                System.out.println(a);
            }
        }
    }
    

    приведет к ошибке

    
    Error:(8, 17) java: variable a is already defined in method main(java.lang.String[])
    

    Что и не удивительно =)

    А вот если в данном примере сначала объявить переменную сначала внутри цикла for, а затем повторно ее объявить уже за пределами цикла ниже:

    
    public class Test {
        public static void main(String[] args) {
    
            int i;
    
            for (i = 0; i < 10; i++) {
    
                int a;
                a = 5 + i;
    
                System.out.println(a);
            }
    
            int a;
            a = 100;
    
            System.out.println(a);
        }
    }
    

    То ошибки уже не будет, так как переменная «a» будет иметь разные области действия! То есть первое объявление переменной «a» ограничивает ее область действия циклом, и когда цикл заканчивается, то она перестает существовать и ее повторное объявление уже допустимо. Но с точки зрения логики и стиля кода, такого лучше избегать, так как может привести к путанице при отладке кода.

    Арифметические операции над переменными.

    Самое простое и интуитивно понятно из всего, что есть! Это простые математические операции такие «сложение«, «вычитание» и т.д.

    Арифметические операции над переменными

    Исключение составляют лишь операции деления по модулю, инкремент и декремент

    Деление по модулю (остаток от деления) «%«

    Деление по модулю — арифметическая операция, результатом которой является остаток от деления целого числа на другое целое число.

    Пример кода программы, выполняющей деление по модулю можно посмотреть здесь.

    Дабы не было путаницы, стоит отметить, что это не дробная часть, которая остается после выполнения операции деления. Ну, например:

    10 / 3 = 3,333333333333333

    То есть это не 0,333333333333333! Это то число, которое остается после проверки того, сколько раз число 3 вмещается в 10-ти. Например:

    10 % 3 = 1
    3 + 3 + 3 = 9
    10 – 9 = 1

    Вот такой вот маленький примитивный пример объясняющий работу деления по модулю =)

    Операции инкремента «++» и операция декремента ««

    Инкремент, инкрементирование (от англ. increment «увеличение») — операция во многих языках программирования, увеличивающая переменную на 1.

    Декремент – обратная операция в отличии от инкремента, которая уменьшает значение на 1.

    Как видно из определений, суть этих операций заключается либо в увеличении значения либо его уменьшения на 1. Это было сделано, что бы каждый раз не писать дополнительное математические выражение инкремента типа:

    
    a = a + 1;
    

    или декремента соответственно:

    
    a = a – 1;
    

    каждый раз, когда требуется сделать так сказать один шаг вперед или назад.

    Чаще всего это используется в циклических операциях (цикл for который мы так любим использовать, но до сих пор не прочитали про него).

    У данных операций есть одна особенность, которая заключается в форме их написания, называются они префиксная и постфиксная формы!

    Префиксная форма (++a или —a) – записав выражение в данной форме операция увеличения или уменьшения на 1, будет выполнена до математического вычисления.

    На примере инкремента это выглядит так:

    
    int a = 1;
    int b = 2;
    
    int c = ++a + b;
    

    Если обычно в математике 1 + 2 будет равно 3, то в данном случае все немного иначе, сначала переменная «a» которая была равна 1 будет увеличена на 1, тем самым получит значение 2, а уж затем будет выполнено действие сложения, что в результате даст нам уже 4!

    Постфиксная форма (a++ или a—) – запись выражения в данной форме говорит о том, что сначала будут выполнятся математические операции над переменными, а только потом будет производится увеличение или уменьшение значения на 1. Данная форма используется чаще нежели предыдущая в циклических операция (примелькавшийся нам цикл for).

    На примере инкремента это выглядит так:

    
    int a = 1;
    int b = 2;
    
    int c = a++ + b;
    
    System.out.println(c);
    System.out.println(a);
    

    В данном случае сначала выполнится операция сложения, что даст переменной c значение 3 и только потом переменная a будет увеличена на 1!

    Форма записи этих операций имеет большое значение, так, что путать его нельзя ни в коем случае! Иначе можно получить совсем не тот результат, который ожидаешь.

    — Ферштейн?
    — Яволь хер майор

    Операции отношения и логические операции

    Эти операции являются как по мне фундаментом для операций ветвления и циклов, в которых они чаще всего используются.

    Операции отношения.

    Вот честно, не могу понять кто их так назвал, но как по мне, то лучше было бы назвать их в этой книге «Операции сравнения«. Ибо именно эту роль по сути они и выполняют.

    Они сравнивают значения на равенство, определяют какое значение больше, а какое нет, и исходя из этого дают результат в виде true или false =)

    Примечание: операторы сравнения «<«, «>«, «>=«, «<=» применяются к переменным типа от byte до char, а вот к переменным типа boolean их применение будет не логично.

    И в отличии от математических операций не имеют приоритетов, точнее они, то есть, вот только использовать подобного рода операции строя логику на их приоритете довольно глупо.

    Знак операции Значение
    == равно
    != не равно
    > больше
    < меньше
    >= больше или равно
    <= меньше или равно

    Чаще всего они используются при работе с операторами ветвления (if).

    Логические операции.

    Логические операции в Java

    Операции, суть которых не в сравнении значений, а больше в их объединении в одно выражение.

    Оператор Значение
    & и
    | или
    ^ исключающее или
    || укороченная форма или
    && укороченная форма и
    ! Не

    Например:

    
    if (a == b & c > a) System.out.println("Какой чудесный день!");
    

    Также, как и операции сравнения, результатом их работы будет тоже значение типа boolean.

    Небольшой особенностью данных операций есть то, что некоторые из них имеют «сокращённую форму записи«. Наверно я опять-таки придираюсь, но вот как-то сокращенная форма не совсем похожа на сокращенную, почему, можно посмотреть в таблице выше. Как по мне логичный было бы сделать форму записи наоборот =) Но суть не в этом, ведь имелось в виду будет ли выполнятся все условие или нет!

    В зависимости от формы написания оператора, будет зависеть выполнение поставленного условия целиком или только его одна часть! Например, если написать условие используя сокращенную форму оператора «и«:

    
    if (a != 0 && (b % a) == 0) {
        //здесь какая-то операция
    }
    

    В данном случае проверится только первая часть условия, а вторая будет проигнорированная если переменная «a» будет равна нулю, следовательно, операция внутри не будет выполнятся (так предотвращается деление на ноль). А вот если записать данное условие без использования сокращенной формы:

    
    if (a != 0 & (b % a) == 0) {
        //здесь какая-то операция
    }
    

    То будут проверятся оба условия, в результате чего будет произведена операция деления на ноль =)

    В данных случаях нужно стоить логику программы в зависимости от того, нужно ли проверять оба условия или можно только одно!

    Вот, пожалуй, и все, что стоит сказать об этих операция.

    Ниже приведена таблица значений, получаемых в результате выполнения логических операций «и«, «или«, «исключающее или«, «не«; если использовать в качестве значений, значения типа boolean:

    a b a & b a | b a ^ b !a
    false false false false false true
    true false false true true false
    false true false true true true
    true true true true false false

    Использование круглых скобок

    По мимо уже известного математического свойства повышения приоритета выполнения операций, у них есть еще одно приятное свойство. Это повышение читабельности кода, что существенно упрощает разбор чужого кода! Ну, например:

    
    a = 10 / b + a * d – 2
    

    И так

    
    a = (10 / b) + (a * d) – 2
    

    Очевидно же, что так читать это выражение легче, несмотря на знание приоритетов выполнения математических операций.

    Оператор присваивания и его укороченная форма

    Операция присваивания

    Пожалуй, самое простое, что есть =)

    Это операция, когда происходит инициализация переменной или присваивание ей нового значения.

    
    a = 10;
    

    или так

    
    a = b = c = 20;
    

    Это пример данной операции. В последнем случае происходит присваивание сначала переменной «c» затем «b» и только потом «a«, использовать его не рекомендуется, как говорят – это плохая практика.

    Укороченная форма операции присваивания

    Здесь не так как с логическими операторами! Особенность данной операции состоит упрощении определенного действия:

    
    a = a + 10;
    

    То есть это так сказать более расширенная форма инкремента и декремента, когда нужно увеличить значение переменной на какое то определенной значение. И дабы не писать математическое выражение полностью, можно записать его в упрощенной форме:

    
    a += 10;
    

    и это будет тоже самое.

    Данная форма может использоваться на всех математических операциях и на части логических операций:

    Преобразование и приведение типов данных

    При присваивании

    Не смотря на то, что Java является строго типизированным языком программирование в нем существует так называемые понятия расширение типов и автоматическое преобразование.

    Автоматическое расширение – это преобразование переменной одного типа в другой, без участия программиста, но при соблюдении условий: типы должны быть совместимы и если тип в какой будет преобразовываться другой имеет более широкий диапазон значений.

    Расширение типов – как было сказано выше, это когда переменная с более низким диапазоном значений преобразовывается в тип с более высоким значением.

    Примечание: нельзя автоматически преобразовать одну переменную в другу, если диапазон ее значений у конечной переменной другого типа меньше чем у нее самой.

    Более полное описание можно было прочитать выше в «Что такое простые типы данных«

    Для примера можно привести следующий код:

    
    class LtoD {
        public static void main(String[] args) {
    
            long L;
            double D;
            
            L = 100123285L;
            D = L; // Автоматическое преобразование long в double
    
            //L = D; выдаст ошибку!! так как нельзя преобрзовать double в long
            System.out.println("L и D: " + L + " " + D);
        }
    }
    

    Здесь переменная типа long автоматически на уровне компилятора преобразовывается в тип double так как у него диапазон допустимых значений для хранения больше. А вот наоборот автоматически преобразовать нельзя, так как компилятор выдаст ошибку:

    
    Error:(11, 13) java: incompatible types: possible lossy conversion from double to long
    

    Но это не повод для расстройства, так как здесь на помощь придет такая вещь как «приведение несовместимых типов«.

    Приведение несовместимых типов

    Это преобразование одного типа данных у которого диапазон значений больше, в тот у которого он меньше! Например, тот же тип double из примера выше в тип long.

    Делается это просто, нужно лишь соблюсти формат записи

    тип переменная = (нужный_тип) преобразуемая_переменная;

    Ну может не совсем просто =) Нужно помнить две вещи:

    Тип переменной и тип второй в которую происходит преобразование должны совпадать.

    Нельзя переменную одного типа преобразовать в совершенно другой тип! Звучит сумбурно, но на примере станет ясней:

    
    int a;
    long b = 20;
    a = (double) b;
    

    Это приведет к ошибке:

    
    Error:(8, 13) java: incompatible types: possible lossy conversion from double to int
    

    То есть типы не должны перескакивать один через другой, так сказать перепрыгивать через голову. Они должны бить либо идентичными, либо же меньше. Например, так:

    
    int a;
    long b = 20;
    
    a = (short или int) b;
    

    И очень важно помнить, что при таком приведение, часть значения может потеряться или произойдет переполнение типа! И значение будет не таким каким мы его ожидаем увидеть =)

    На примере это будет выглядеть так:

    
    int a;
    duble b = 20.5;
    
    a = (int) b;
    

    В данном случае переменная преобразуется из типа double в int, но если вывести полученное значение на экран, то выведется только число 20, а оставшиеся 0,5 пропадут =)

    Преобразование типов в выражениях

    Еще одной занимательно особенностью языка Java является это самое автоматическое приведение типов!

    Все дело в том, что по умолчанию используются два типа данных: int и double! Как бы это не звучало парадоксально, но останется фактом =) что все целочисленные переменные при выполнении математических операций будут проходить двойное автоматическое преобразование. Например:

    
    byte a, b, c;
    a = 120;
    b = 9;
    
    c = (byte) (a + b);
    

    Сначала обе переменные будут преобразованы в тип int, затем будет выполнена математическая операция и полученное значение будет преобразовано опять в тип byte.

    Важной особенность здесь является то, что нужно заключать все в скобки, иначе компилятор выдаст ошибку

    
    byte a, b, c;
    a = 120;
    b = 9;
    
    c = (byte) a + b; //ошибка, пропущены скобки
    
    
    Error:(10, 22) java: incompatible types: possible lossy conversion from int to byte
    

    То есть формальная запись будет следующей:

    переменная = (тип_в_который_преобразуем) (переменная + переменная);

    Таблица приоритета операций начиная от самого высокого и заканчивая самым низким

    ( ) [ ] .  
    ++ — (префиксная форма) ++ — (постфиксная форма) ~< !
    * / %  
    +    
    >> >>> <<  
    > >= < <=
    == !=    
    &      
    ^      
    |      
    &&      
    ||      
    ?:      
    = op=    

    Вот пожалуй и все с чем нас знакомит данная глава в книге. По обычаю найти все примеры из этой главы можно в моем репозитории.

    Остается только привести список вопросов к самопроверке и домашнее задание.

    Список вопросов к самопроверке

    1. Почему в Java строго определены диапазоны допустимых значений и области действия простых типов?

    Ответ: Для обеспечения переносимости программ, то есть кроссплатформенности. Только так можно было быть уверенными, что на разных платформах результат выполнения программ будет одинаковым.

    1. Что собой представляет символьный тип в Java и чем он отличается от символьного типа в ряде других языков программирования?

    Ответ: Символьный тип данных в Java это не что иное как таблица Unicode символов. Это нужно было для того, чтобы дать возможность представлять символы всех языков мира, тем самым сделать язык гибким и популярных во всех странах.

    1. «Переменная типа boolean может иметь любое значение, поскольку любое ненулевое значение интерпретируется как истинное». Верно или неверно?

    Ответ: Нет не верно! Тип boolean может содержать только два значения true или false (истина или ложь). Для каждых видов данных в Java имеется свой тип данных.

    1. Допустим, результат выполнения программы выглядит следующим образом:
    • Один
    • Два
    • Три

    Напишите строку кода вызова метода println(), где этот результат выводится в виде одной строки.

    Ответ:

    
    System.out.println("ОдинnДваnТри");
    
    1. Какая ошибка допущены в следующем фрагменте кода?
    
    for (i = 0; i < 10; i++) {
        int sum;
        sum = sum + 1;
    }
    
    System.out.println("Сумма: " + sum);
    

    Ответ: В данном примере не соблюдена область видимости (действия) переменной, при попытке откомпилировать будет выдана ошибка:

    
    Test.java:16: error: cannot find symbol
    			System.out.println("Сумма: " + sum);
    										   ^
    symbol:   variable sum
    location: class Test
    1 error
    

    Так как переменная sum ограничена областью действия цикла for и за его пределами она не существует. Далее, даже если исправить этот момент, то нельзя использовать переменную предварительно ее не инициализировав со значением согласно типа самой переменной, в результате чего программа выдаст ошибку при компиляции:

    
    Test.java:11: error: variable sum might not have been initialized
    				sum = sum + i;
    				^
    1 error
    

    Если исправить и эту ошибку, то в результате выполнения программы мы получим числа от 0 до 9, вместо суммирования уже имеющихся числе как предполагается. Но это больше логическая ошибка, чем синтаксическая. Связано это с тем, что переменная sum будет жить только до окончания итерации цикла, и уже со следующей итерацией она будет снова инициализирована с начальным значением!

    1. Поясните различие между префиксной и постфиксной формами записи операции инкремента.

    Ответ: Согласно установленного правила префиксная форма инкремента или декремента выполняет действие над переменной до ее использования в выражении, а постфиксная после. Например:

    
    int x, y;
    x = 10;
    y = ++x;
    

    в результате чего x и y будут иметь значение 11, в случае с постфиксной формой все будет немного иначе:

    
    int x, y;
    x = 10;
    y = x++;
    

    здесь y будет равна 10, а x будет равна 11.

    1. Покажите, каким образом укороченная логическая операция И может предотвратить деление на нуль.

    Ответ:

    
    class SCops {
        public static void main(String[] args) {
    
            int n, d, q;
            d = 0; // установить для d нулевое значение
    
            // Второй операнд не вычисляется, поскольку значение переменной d равно  нулю
            if (d != 0 && (n % d) == 0) {
    
                System.out.println(d + " является делителем " + n);
            }
    
            /* А теперь те же самые действия выполняются без использования укороченного
             логического  оператора. В результате возникает ошибка деления на нуль:
             Exception in thread "main" java.lang.ArithmeticException: / by zero
             at SCops.main(SCops.java:*)
            */
    
            if (d != 0 & (n % d) == 0) {
                System.out.println(d + " является делителем " + n);
            }
        }
    }
    

    В результате работы укороченной формы логической операции И в отличии от ее полной записи, выполняется проверка только первого условия и если оно ложно, то дальнейшее вычисление уже не выполняется.

    1. До какого типа повышаются типа bute и short при вычислении выражений?

    Ответ: До типа int.

    1. Когда возникает потребность в явном приведении типов?

    Ответ: Потребность в явном приведении типов возникает в случаи, когда результат выполнения выражения нужно привести к конкретно типу данных. Например, вместо double нужно получить значение типа int:

    
    double x, y;
    int d;
    
    d = (int) (x + y);
    

    в этом случае результатом вычисления будет цело число (его дробная часть потеряется) типа int. Так же и с другими совместимы типами. Такое встречается не часто и поэтому нужно самому внимательно следить за типами данных и их диапазонами, дабы не получить неожиданный результат!

    1. Оказывают ли избыточные скобки влияние на эффективность выполнения программ?

    Ответ: Нет, избыточные скобки напротив делают код более читабельным и логичным, но злоупотреблять ими не стоит.

    1. Определяет ли блок кода область действия переменных?

    Ответ: Да. Переменная объявленная внутри какого-то блока кода, будет недоступно за его пределами, исключение являются только глобальные переменные или переменные класса. То есть если к примеру, переменная была объявлена внутри цикла, то за пределами цикла она уже не существует, а потому будет недоступна! А переменные объявленные до того же цикла, напротив будут доступны внутри цикла.

    Домашнее задание

    Первое

    Условие: Изменить программу из примера 2.1 таким образом, чтобы она рассчитала расстояние до крупного объекта по времени за которое вернется эхо. Так если хлопнуть в ладоши, то время за которое вернется эхо, будет равно времени прохождению звука в прямом и обратном направлении.

    Листинг программы:

    
    class Echo {
        public static void main(String[] args) {
    
            double sound;
            double dist;
    
            sound = 7.2 / 2;     // Рассчитываем время за которое мы услышим эхо, разделив его на 2, узнаем время до объекта без его возврата к нам
            dist = 1100 * sound; // Рассчитываем расстояние до объекта
    
            System.out.println("Расстояние до скалы равно " + dist + " фута");
        }
    }
    

    По принципу решения, программа довольна проста, создаются две переменные типа double «sound» и «dist«. Затем исходя из условия, берем время, за которое звук доходит до наблюдателя, он равен 7.2 секунды, и делим его на 2, чтобы узнать время, которое преодолевает звук в одну сторону. Ну, а потом приступаем к расчету расстояния до искомого объекта, для этого мы берем скорость распространения звука в воздухе, она равна 1100 футов в секунду, и умножаем ее на полученный результат от первой операции. В итоге получаем желаемый результат.

    Второе

    Условие: Напиши программу, которая находила бы простые числа от 2 до 100.

    Вот тут признаюсь честно, ее я не решил в виду плавающих знаний о циклах, но честно и добросовестно разобрался в ней от и до.

    Для начала стоит понять, что такое простые числа?!

    Простое число (др.-греч. πρώτος ἀριθμός) — натуральное (целое положительное) число, имеющее ровно два различных натуральных делителя — единицу и самого себя. Другими словами, число x является простым, если оно больше 1 и при этом делится без остатка только на 1 и на x. К примеру, 5 — простое число, а 6 является составным числом, так как, помимо 1 и 6, также делится на 2 и на 3.

    Учитывая, что данную тему, уже раскрыли и она ни для кого не секрет, то для определения правильности решения, можно посмотреть в таблицу простых чисел.

    Там же можно немного сжульничать и взять алгоритм решения:

    Решетка Эратосфена

    1. Выписать подряд все целые числа от двух до n (2, 3, 4, …, n).
    2. Пусть переменная p изначально равна двум — первому простому числу.
    3. Зачеркнуть в списке числа от 2p до n считая шагами по p (это будут числа кратные p: 2p, 3p, 4p, …).
    4. Найти первое не зачёркнутое число в списке, большее чем p, и присвоить значению переменной p это число.
    5. Повторять шаги 3 и 4, пока возможно.

    Теперь этот алгоритм можно перевести в код:

    
    class PrimeNumber {
        public static void main(String args[]) {
    
            int i, j;
            boolean isprime;
    
            for(i=2; i < 100; i++) {
    
                isprime = true;
    
                // проверить, делится ли число без остатка
                for(j = 2; j <= i / j; j++)
    
                    // если число делится без остатка, значит, оно не простое
                    if((i % j) == 0) isprime = false;
    
                if (isprime) System.out.println(i + " - простое число.");
            }
        }
    }
    

    Задаем две переменные «i» и «j» типа int, и одну переменную «isprime» типа boolean.

    Далее создаем первый цикл, который будет выполнятся почти 100 раз и будет начинаться с 2, так как это первое простое число (оно больше 1 и делится только на 1, и само на себя). Так же установим значение переменной isprime равным true по умолчанию.

    Затем создаем второй цикл, в нем и происходит вся магия! В нем мы устанавливаем значение переменной «j» равное 2, условием выхода из этого цикла будет момент, при котором переменная «j» будет больше или равна математическому выражению, в котором переменная «i» будет делится на переменную «j«.

    Если забежать немного наперед, то хоть циклы так же, как и логические операции, это материал следующей главы, но ознакомится с их работой можно тут:

    Ну, а если вкратце, то выполнятся они будут только при условии, что заданное условие будет иметь значение true.

    Теперь можно идти дальше! Теперь мы создадим два логических оператора if. В первом будем проверять делится ли число без остатка, путем деления по модулю, если число делится без остатка, то условие будет истинно и переменной isprime будет присвоено значение false. Этот логический оператор if будет принадлежать вложенному циклу for, учитывая, что они записаны в сокращенной форме (без фигурных скобок, их бы лучше ставить, ибо так проще читать код).

    Во втором будет проверятся значение переменной isprime на предмет истинности (забегая немного наперед скажу, что оператор if выполняется только в случае если заданное ему условие как раз таки истинно) и если это так, то на экран будет выводится сообщение, что такое то число является простым!

    Не понятно? Вот так и мне было по началу =)

    Но как сказал один человек «не можешь понять, распиши на листочке!». Что мы сейчас и сделаем!

    Цикл расписанный на листочке

    Первое значение переменной «i«, которое поступает на вход равно 2, далее устанавливается значение переменной isprime как true, и переходит к вложенному циклу. В нем значением переменной «j» тоже равно 2.

    Идет проверка условия выхода с цикла 2 <= 2 / 2? Нет 2 больше 0 значит цикл заканчивается, и первый оператор if так и не выполняется, так как достигнуто условие выхода из цикла, еще до его начала! И дальше управление передается второму оператору if где идет проверка переменной isprime на предмет истинности, а учитывая, что она по умолчанию равна true, то на экран будет выведен надпись:

    2 — простое число.

    На этом заканчивается первая итерация и начинается все сначала!

    Для сокращения количества текста и того, что основной принцип уже описан, я распишу все в цифрах на примере двух итераций первого цикла =)

    И так приступим.

    
    //Вторая итерация первого цикла
    for (i = 3; 3 < 100; 3++) {
    
        isprime = true;
    
        for (j = 2; 2 <= (3 / 2 = 1.5); 2++) //значение условия выхода с цикла будет false
            if((3 % 2) == 0) isprime = false; //эта строка не будет обрабатываться так как цикл закончен и не было ни одной итерации
        
        if (isprime) System.out.println(3 + " - простое число."); //эта операция будет иметь значение true и на экран будет выведен текст "3 - простое число."
    }
    
    //Третья итерация первого цикла
    for (i = 4; 4 < 100; 3++) {
    
        isprime = true;
    
        for (j = 2; 2 <= (4 / 2 = 2); 2++) //значение условия выхода с цикла будет true и цикл запустится на выполнение
            if ( ( (4 % 2) == 0 ) ) isprime = false; //эта строка выполнится так как значение логического условия будет true и переменная isprime получит значение false
    
        if (isprime) System.out.println(3 + " - простое число."); //эта операция получит значение false и на экран ничего не выведется, так как число 4 не является простым
    }
    
    //Четвертая итерация первого цикла
    for (i = 5; 5 < 100; 3++) {
    
        isprime = true;
    
        //Первая итерация вложенного цикла
        for (j = 2; 2 <= (5 / 2 = 2.5); 2++) //значение условия выхода с цикла будет true и цикл запустится на выполнение
    
            if ( (((5 % 2) == 0) = 1) ) isprime = false; //эта строка не будет выполнена так как результат логического условия будет false
    
        //Вторая итерация вложенного цикла
        for (j = 3; 3 <= (5 / 3 = 1.666…); 2++) //значение условия выхода с цикла будет false и цикл будет прерван
            if ( (((5 % 3) == 0) = 2) ) isprime = false; //эта строка не будет обрабатываться так как цикл закончен
    
        if (isprime) System.out.println(5 + " - простое число."); //эта операция будет иметь значение true и на экран будет выведен текст "5 - простое число."
    }
    

    Вот, пожалуй, и все! Такой способ отладки и проверки конечно не используется в виду очевидных факторов, так что тема отладки приложений это уже отдельная глава =). Но для наглядности в данном примере очень даже ничего =)

    Теперь осталось только привести ссылки на все примеры из книги, включая упражнения и домашние задания.

    Ссылки на примеры и коды програм

    • Расчет числа кубических дюймов в кубе объемом в 1 куб. милю
    • Определение длины гипотенузы, исходя из длины катетов, по теореме Пифагора
    • Символьные переменные
    • Демонстрация использования логических значений
    • Упражнение 2.1
    • Демонстрация управляющих последовательностей в символьных строках
    • Демонстрация динамической инициализации
    • Демонстрация области действия блока кода
    • Демонстрация времени жизни переменной
    • Повторное объявление переменной после ее объявления
    • Демонстрация использования операции деления по модулю «%»
    • Демонстрация использования операций сравнения и логических операций
    • Демонстрация использования укороченных логических операций
    • Демонстрация роли побочных эффектов
    • Демонстрация автоматического преобразования типа long в тип douЫe
    • Демонстрация приведения типов
    • Упражнение 2.2
    • Неожиданный результат повышения типов!
    • Приведение типов для правильного вычисления выражения
    • Коды программ домашних заданий

    Понравилась статья? Поделить с друзьями:
  • Error incompatible types possible lossy conversion from double to float
  • Error incompatible types object cannot be converted to
  • Error incompatible types nonexistentclass cannot be converted to annotation
  • Error incompatible types java
  • Error incompatible types in assignment