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

Teacher Russell
Teacher Russell
16,873 Points

Java Type Casting

I understood everything discussed in the video, but I've struggled with this challenge for days. I've looked at various answers, am amazed they arrived at that from the question, and still get confused when I read the question. Can anyone give an alternative explanation of what the challenge is asking and how you arrive at each step?

I've only seen the completed challenge. Yes, I'm really that confused:) I'd love to see an answer that I can also know for sure, is the best answer Treehouse was looking for.

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.
    String result = "";
    return result;
  }
}

1 Answer

andren
andren
28,558 Points

I'll try breaking down both the question and the answer in as much detail as I am able. Be forewarned that this ended up being a very long post, but hopefully it clears some stuff up for you.

The question is essentially stating that it will call your method twice. The first time it will pass in a String that has been cast as an Object, the second it will pass in a BlogPost object that has been cast as an Object. The reason that both String and BlogPost objects can be cast as Object is that all objects in Java inherit from the Object class. Hence literally all classes can be cast as Object.

And based on what it passed in it expects different things returned. If the Object passed in started out as a String it expects you to simply cast it back to a String and assign it to the result variable which is returned at the end of the method. If the Object passed in started out as a BlogPost it expects you to cast it back to BlogPost and then pull out the title property from the BlogPost and assign that to the result variable.

While I have no way of knowing how the code for the challenge checker is written I can make an educated guess that it looks approximately like this:

// Initialize test String and BlogPost
String stringVariable = "Test String";
BlogPost blogPostVariable = new BlogPost(
  "Test Author",
  "Test Title",
  "Test Body",
  "Test Category",
  new Date());

// Cast the String and BlogPost to Object variables
Object stringObj = (Object)stringVariable;
Object blogPostObj = (Object)blogPostVariable;

// Pass in the String that has been cast as Object and store the result in a variable
String stringResult = TypeCastChecker.getTitleFromObject(stringObj);

// Pass in the BlogPost that has been cast as Object and store the result in a variable
String blogPostResult = TypeCastChecker.getTitleFromObject(blogPostObj);

// Then for task 1 it will check that stringResult equals the passed in string
// For task 2 it will also check that blogPostResult equals the title of the BlogPost

At first you might assume that you can handle the string casting like this:

public static String getTitleFromObject(Object obj) {
  // Fix this result variable to be the correct string.
  String result = "";
  // Cast obj as string and assign it to result
  result = (String)obj;
  return result;
}

And you would be partially right, that would take care of the string casting, but it would not work for this method because the moment a BlogPost was passed in the code would crash. This is due to the fact that you are asking Java to cast the Object into a String without checking that it is a String first. And casting an object wrongly causes crashes.

So the first thing you must do for this method to work is to figure out whether the Object passed in can actually be cast as a String at all. Doing so is actually pretty simple, in the previous video the instanceof keyword was demonstrated. That keyword allows you to check that an object is actually an instance of a specific class, and it works regardless of what the object is currently cast as.

So by combining that with a conditional statement like if you can verify that the passed in Object is actually an instance of the String class. Once you have done that it is safe to cast it. So the solution to the first task becomes this:

public static String getTitleFromObject(Object obj) {
  // Fix this result variable to be the correct string.
  String result = "";
  // Check if obj is an instance of the String class
  if (obj instanceof String) {
    // Cast obj as string and assign it to result
    result = (String)obj;
  }
  return result;
}

Now your method will work with strings, and not crash even if a BlogPost object is passed in. But you are obviously not done yet, while the method won't crash when encountering a BlogPost it also won't actually do anything with it.

So it's time to start working on the code for task 2, which requires you to ultimately pull the title property from the passed in BlogPost and assign it to result. The first step of this task is the same as task 1, you have to check if the passed in Object is actually an instance of BlogPost. And you do that in the exact same way as you did before.

The problem comes with what you are then supposed to do. There are actually two things you can do, one simple but long solution and one shorter but a bit more complicated. I'l cover the long one first. That is to create a BlogPost variable and assign it the casted obj, then assign the title property (which you can get through the getTitle getter) to the result variable. Like this:

 public static String getTitleFromObject(Object obj) {
  // Fix this result variable to be the correct string.
  String result = "";
  // Check if obj is an instance of the String class
  if (obj instanceof String) { 
    // Cast obj as string and assign it to result
    result = (String)obj;
  }
  // Check if obj is an instance of the BlogPost class
  if (obj instanceof BlogPost) {
    // Cast obj as BlogPost and assign it to a new variable
    BlogPost castBlogPost = (BlogPost)obj;
    // Get title through getTitle getter and assign it to result
    result = castBlogPost.getTitle();
  }
  return result;
}

The more complex option is to cast the obj as a BlogPost object, then call getTitle and then assign that to the result variable all in one line. This can be done through clever use of parenthesis (). Java executes code that is wrapped in parenthesis before it executes code outside it. Here is the example solution:

public static String getTitleFromObject(Object obj) {
  // Fix this result variable to be the correct string.
  String result = "";
  // Check if obj is an instance of the String class
  if (obj instanceof String) { 
    // Cast obj as string and assign it to result
    result = (String)obj;
  }
  // Check if obj is an instance of the BlogPost class
  if (obj instanceof BlogPost) {
    // Cast obj and call getter and assign it to result
    result = ((BlogPost)obj).getTitle();
  }
  return result;
}

In the above code (BlogPost)obj get executed before the getTitle call since it is wrapped in parenthesis. So the getTitle call ends up being called on the resulting casted object, rather than being cast on obj itself which it normally would.

If there is still something you have questions about, or there was something I brought up that confused you, then feel free to ask followup questions. I'll gladly answer anything I'm able to.

Teacher Russell
Teacher Russell
16,873 Points

1,000 thank you's. I don't know why, but even from your first couple of paragraphs, I was able to solve the first part, and take a sloppy stab at the 2nd. This challenge should have been a video, and your explanation and answer should be the solution video that follows. I'm going to spend some time on this topic and this is a great kick start. I'll try to fine someone more confused than me and share a well thought answer as well.