CodeGym /Courses /New Java Syntax /Reference type conversions

Reference type conversions

New Java Syntax
Level 12 , Lesson 6
Available
Reference type conversions - 1

"And now, a short lesson from Diego. Brief and to the point. About reference type conversions."

"Let's start with Object variables. You can assign any reference type to such a variable (widening conversion). However, to make the assignment in the other direction (narrowing conversion), you must explicitly indicate a cast operation:"

Code Description
String s = "mom";
Object o = s; // o stores a String
A typical widening reference conversion
Object o = "mom"; // o stores a String
String s2 = (String) o;
A typical narrowing reference conversion
Integer i = 123; // o stores an Integer
Object o = i;
Widening conversion.
Object o = 123; // o stores an Integer
String s2 = (String) o;
Runtime error!
You cannot cast an Integer reference to a String reference.
Object o = 123; // o stores an Integer
Float s2 = (Float) o;
Runtime error!
You cannot cast an Integer reference to a Float reference.
Object o = 123f; // o stores a Float
Float s2 = (Float) o;
Conversion to the same type. A narrowing reference conversion.

"A widening or narrowing reference conversion doesn't change the object in any way. The narrowing (or widening) part specifically refers to the fact that the assignment operation includes (does not include) type-checking of the variable and its new value."

"This is the rare example where everything is clear."

"To avoid the errors in these exampleswe have a way to find out what type is referenced by the Object variable:"

Code
int i = 5;
float f = 444.23f;
String s = "17";
Object o = f;                       // o stores a Float

if (o instanceof  Integer)
{
    Integer i2 = (Integer) o;
}
else if (o instanceof  Float)
{
    Float f2 = (Float) o;            // This if block will be executed
}
else if (o instanceof  String)
{
    String s2 = (String) o;
}

"You should perform this check before every widening conversion unless you are 100% sure of the object's type."

"Got it."

Comments (31)
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION
Hoist Level 4, San Diego, United States
4 April 2023
See Ivan summary below --
MrPreston Level 11, Edinburgh, United Kingdom
6 July 2021
Think of reference types (Class objects) as a set of buckets. Object class is the biggest bucket, so ANY other reference type (class) can be placed in the Object bucket no problem (no casting). But if you wanted to take a big bucket (like object) and put it into a smaller bucket you need to state you are okay with losing some data/precision and so you must cast. Strings, Longs, Integer, Doubles, Cats, Dogs, etc...can all be assigned to their own object reference. But the other way round requires you to cast your types/references. Now imagine you have a Dog class. and You also have a Labrador class that extends the Dog class. This means the Dog bucket is bigger than the Labrador bucket. So you can put a Labrador instance into a dog reference without casting. But if you want to assign a dog to the lab class you must cast.

   public static void main(String[] args) {
        Dog dog = new Dog();
        Lab lab = (Lab) dog;

        Lab lab2 = new Lab();
        Dog dog2 = lab2;
    }

    static class Dog {
    }

    static class Lab extends Dog {
    }
Sinisa Level 11, Banja Luka, Bosnia and Herzegovina
26 March 2021
"You should perform this check before every widening conversion unless you are 100% sure of the object's type." This check should be performed before every narrowing conversion, that is what you've wanted to say, right 😏
Syed Umar Level 1, Gothenburg , Sweden
13 March 2021
This is the first time,I regret visiting the comments section🤣 You guys confused me more now what is right and what is wrong!
Jurij Thmsn Level 29, Flensburg, Germany
1 February 2021
I don't get why in the article it says "Let's start with Object variables. You can assign any reference type to such a variable (narrowing conversion). However, to make the assignment in the other direction (widening conversion), you must explicitly indicate a cast operation:" - I understand: narrowing conversion - ok. widening conversion - use cast operator. But in the following examples it is the exact opposite: when there is a narrowing conversion - cast is used. I am really confused.
DarthGizka Level 24, Wittenberg, Germany
31 May 2021
The use of the terms 'narrowing' and 'widening' in the context of object references is pure nonsense (perhaps it was meant to make people comfortable hearing terms used in the previous lecture). The real rule is easy: object references can be converted *implicitly* to any less specific type (base class or interface) but explicit casts are necessary for conversion of a less specific *declared* type to a more specific one (e.g. base class reference or interface to actual class).

Integer i = 42;
Object o = i;
Integer j = (Integer)o;
Object boxed = 666;
i += boxed;
For i, the declared and actual types coincide. The assignment of i to o performs an implicit conversion to a reference of type Object, which is the base class of all objects in Java. The variable o has the declared type Object but it holds on object whose actual type is Integer. Casting o back to its actual type requires an explicit cast, but it cannot fail. In the penultimate line a raw integer is assigned to an object variable. In this context the raw value - which is a so-called a 'primitive type' in Java - gets automatically boxed ('wrapped') into its boxed type, Integer, which is an object type. In the last line that boxed value gets added to a raw integer; the value gets pulled out its box and added.
Jonaskinny Level 25, Redondo Beach, United States
15 February 2022
It actually says (as of 2/2022) widening to object, narrowing from object, correct in both cases.
Dmitri Level 22, Seversk, Russia
16 November 2020
how come that this is narrowing (from this article) - Object o = "mom"; // o stores a String String s2 = (String) o; but this is widening (also from this article) - Object o = 123f; // o stores a Float Float s2 = (Float) o; ??
Andrei Level 41
17 November 2020
Good question, maybe someone more experienced can answer!
Gellert Varga Level 23, Szekesfehervar, Hungary
18 January 2021
Because CodeGym sometimes has mistakes (typo). This is one of them. To cast an Object type variable (Object o) to any child-class type (Float s2): it's narrowing.
John Squirrels Level 41, San Francisco, Poland
19 January 2021
Thank you noticing it. We double check it first from our end once again. If you're right, then we correct it immediately.
Chandan Thapa Level 22, Dubai, United Arab Emirates
3 November 2020
well understood!
Ryan Level 16, Ashburn, United States
19 July 2020
To help everyone not go through what I did, the terms widening and narrowing are wrong here and you learn the correct terms in Lesson 14 Lecture 3: "Moving up the inheritance chain is called widening, because it leads to a more general type. " When a cast operator is needed remains consistent though, you need a cast operator when you go from the base class (or parent class) to the inheriting class (or child class). You can verify this in the Oracle documentation: https://docs.oracle.com/javase/specs/jls/se8/html/jls-5.html#jls-5.1.5
Ryan Level 16, Ashburn, United States
19 July 2020
Here is my understanding from reading the Oracle documentation: 1. Moving up the inheritance chain is widening (going from child class to parent class). 2. Moving down the inheritance chain is narrowing (going from parent class to child class). 3. A cast operator is required when narrowing (going from parent class to child class).
Nikitata Level 22, Ba Sing Se, United States
13 July 2020
Has anybody discovered the copy text hack?? Recently figured it out, but it is good practice to complete these tasks. Highlight the text, then double click. Click on the "Copy" option and Ctrl-V the code into the "Your Code:"... Useful when you're at rock bottom with these copy-paste tasks