Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Java Java Data Structures - Retired Getting There Type Casting

Brandon Chong
Brandon Chong
4,238 Points

Need clarification on why you cannot typecast obj back into obj...

Why does the following not work? obj = (BlogPost) obj;

Is it because obj is defined as an object, so you cannot typecast a BlogPost into a variable name that is defined as an object?

I finished the challenge but I had to rename the variable, ex. BlogPost anotherObj = (BlogPost) obj;

I'm just curious as the reason behind why I had to do this?

com/example/BlogPost.java
package com.example;

import java.util.Date;

public class BlogPost {
    private String mAuthor;
    private String mTitle;
    private String mBody;
    private String mCategory;
    private Date mCreationDate;

    public BlogPost(String author, String title, String body, String category, Date creationDate) {
      mAuthor = author;
      mTitle = title;
      mBody = body;
      mCategory = category;
      mCreationDate = creationDate;
    }

    public String getAuthor() {
      return mAuthor;
    }

    public String getTitle() {
      return mTitle;
    }

    public String getBody() {
      return mBody;
    }

    public String getCategory() {
      return mCategory;
    }

    public Date getCreationDate() {
      return mCreationDate;
    }
}
TypeCastChecker.java
import com.example.BlogPost;

public class TypeCastChecker {
  /***************
  I have provided 2 hints for this challenge.
  Change `false` to `true` in one line below, then click the "Check work" button to see the hint.
  NOTE: You must set all the hints to false to complete the exercise.
  ****************/
  public static boolean HINT_1_ENABLED = false;
  public static boolean HINT_2_ENABLED = false;

  public static String getTitleFromObject(Object obj) {
    // Fix this result variable to be the correct string.
    if (obj instanceof BlogPost) {
      obj = (BlogPost) obj;
    }
    String result = "";
    return result;
  }
}

2 Answers

Christopher Augg
Christopher Augg
21,223 Points

Brandon,

Actually, obj is considered a local variable because it is being passed in to the getTitleFromObject method. Therefore, java will complain with a "Duplicate local variable obj" as soon as you attempt to type it with a declaration.

      public static String getTitleFromObject(Object obj) {
          if (obj instanceof BlogPost) {
              BlogPost obj = (BlogPost) obj; //error: Duplicate local variable obj
          }
      }

Furthermore, it is always a good practice to name our variables with names that represent the objects we are referring to for clarity like the following:

        BlogPost blogPost = (BlogPost) obj;

As for your question, the answer is that you absolutely can write code like this:

       if(obj instanceof BlogPost) {
            obj = (BlogPost)obj;
        }

It will compile but all that is doing is taking the reference of obj and passing it back into itself. Remember, obj is already holding a reference to BlogPost when it is passed into the getTitleFromObject method . Therefore, you are back to where you started with a variable of type Object named obj that holds a reference to a BlogPost object. And we definitely do not want this because we loose access to the BlogPost methods when an Object type is holding the reference to one of our other objects like BlogPost. That is the reason we want to cast it to a BlogPost type in the first place.

I typed up some code using a Lamp object that you can play around with to help clarify this further. All you need to do is make two new files. One named MAIN.java, and the other named Lamp.java. Then copy the respective code into the files, save, compile, and run. I commented the the MAIN class to show each step.

MAIN.java

       public class MAIN {

    public static void main(String[] args) {

        // Create a lamp object.
        Lamp lamp = new Lamp(60, "ACME");
        // Assign a lamp object to an Object type named obj
        Object obj = lamp;
        // Print the class for this object. We can see that obj refers to a lamp
        System.out.println(obj.getClass());
        // Print the reference of obj
        System.out.println(obj);
        // Cast obj as a lamp back into obj. This is valid code that will compile, but.....
        obj = (Lamp) obj;
        // Print the reference of obj. We see that we just passed its reference
        // back into itself for no reason.
        System.out.println(obj);
        //Another issue is that we want access to the methods of the Lamp
        System.out.println(lamp.getType());
        // Do we get that with obj? ...uncomment and look at error
        //System.out.println(obj.getType());

    }   
}

Lamp.java

       public class Lamp {

    private static final String TYPE = "Lamp";
    private int mWatts;
    private String mNameBrand;
    private boolean mOnOffState;


    public Lamp(int tWatts, String tNameBrand) {
        mWatts = tWatts;
        mNameBrand = tNameBrand;
        mOnOffState = false;
    }

    public boolean getState() {
        return mOnOffState;
    }

    public void turnOn() {
        mOnOffState = true;
    }

    public void turnOff() {
        mOnOffState = false;
    }

    public int getWatts() {
        return mWatts;
    }

    public String getNameBrand() {
        return mNameBrand;
    }

    public String getType() {
        return TYPE;
    }
}

I hope this helps.

Regards,

Chris

Nico Julian
Nico Julian
23,657 Points

Hi there,

I think it's possible to reuse obj as a variable name, but it does need a data type on the declaration side when you're typecasting it from an Object to a BlogPost. That way, it tells it you're creating a new BlogPost also called obj, which will be the result of casting the Object type obj into a BlogPost. Without the type declaration, it'll try to cast obj into a BlogPost, then stuff it back into the original variable.

public static String getTitleFromObject(Object obj) {
    if (obj instanceof BlogPost) {
      BlogPost obj = (BlogPost) obj;
    }
}