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 Getting There Type Casting

Michael Hughes
PLUS
Michael Hughes
Courses Plus Student 1,847 Points

Casting from a type Object to a type String

I keep getting a runtime error message from the in-browser compiler that I'm not converting a BlogPost object (notice the import statement at the top) to a type String. The thing is they both extend the Java Object class, so do I first need to cast BlogPost to an Object, then cast it to a string? In my code, I'm casting the Object "obj" to a string already, and since it has to accept a parameter type of Object, why is there a difficulty of converting BlogPost to type String since it IS A(n) object? Or is it merely a problem of understanding what the question is asking me to do? Or is it my syntax? (I assume it's a variety of those..).

Thanks in advance for any help/advice!

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 return statement to be the correct string.
    if (obj instanceof String) {
      return (String) obj;
    }
    else {
      String newObj = (String) obj;
      return newObj;
    }
  }
}

10 Answers

Hi Michael,

This one had me scratching my head for ages too!

The issue is that you need to call the getTitle() method if the obj object is of type BlogPost.

This isn't as easy as it sounds. I tried all sorts but eventually took the question literally. Cast the obj to a BlogPost then call the getTitle() method on it; return that.

My solution looks like:

  public static String getTitleFromObject(Object obj) {
    // Fix this return statement to be the correct string.
    if (obj instanceof String) {
      return (String) obj;
    } else {
      return ((BlogPost) obj).getTitle(); 
    }
  }

I hope that helps!!

Steve.

Craig Dennis
STAFF
Craig Dennis
Treehouse Teacher

HINT 3: Cast it to a new BlogPost variable, then return the results of the getTitle() method.

Hope that helps!

Hi Craig,

Great course - thanks! But that one challenge was a little left-field - a tricky little one!

Steve.

Michael Hughes
Michael Hughes
Courses Plus Student 1,847 Points

One suggestion I have, as far as clearing up any confusion from the expectations of what the question is asking the student to do, would be to include the BlogPost.java file on the in-browser compiler as well. For instance, though I was certain that I had created a 'getter' method for the author, body, title, etc. attributes of the BlogPost class, I still (as an unconfident, learning student) wasn't certain if you were shorthandedly referring to the method "getTitleFromObject" as "getTitle" in the last few words of the task.

If the file BlogPost.java were to be included in the compiler window, I would at least be able to get a cue that somehow, answering the question involved referencing some piece of information from the BlogPost.java file and would (perhaps) give me the confidence/direction to cast the file using that class (BlogPost) and that, I could check to see that there was indeed a "getTitle" method in that class as well. I remembered creating the getter methods, but it was a couple videos and tasks prior to this challenge, and since I had learned new material, I had a little bit of a haze remembering them.

I hope this is metacognitive enough to help from a beginner's point-of-view. Also, thanks for making this course, your videos are engaging and incredibly helpful. This is exactly what there needs to be more of on the internets. Any chance you will create a course on Java algorithms as well?

Craig Dennis
Craig Dennis
Treehouse Teacher

Great idea Michael Hughes !

I've added the file for reference. Thanks for the idea!

Josh Gold
Josh Gold
12,207 Points

This challenge was a head scratcher as well partly because of the number of objectives. I think it could be a bit clearer, since this is probably new material for most of us, if it was broken up into roughly four separate pieces.

part 1: check if obj is a String using instanceOf part 2: return obj typecast to String if true part 3: check if obj is an X part 4: return obj typecast as Y if true

Craig Dennis
Craig Dennis
Treehouse Teacher

Thanks Josh Gold great idea I'll see if I can get it to work that way.

Is it ok to have two different returns in a method? Like, the first return being in the first if, and the other return being in the else?

Josh Gold
Josh Gold
12,207 Points

Hello slc, you want to have a return statement for both if and else. It is in fact required.

Hi Josh, I don't know where I got the impression that only one return statement was best, but it's been in my head.

What I decided to do, after some help above, was to use a variable, and then return the variable so that there is only one return

  public static String getTitleFromObject(Object obj) {
    // Fix this result variable to be the correct string.
    String title = "";
    if(obj instanceof String){
      title = (String)obj; 
    }
    if(obj instanceof BlogPost){
      title = ((BlogPost)obj).getTitle(); 
    }
    return title;
  }
Josh Gold
Josh Gold
12,207 Points

Hello slc, What I am trying to say is that all the possible paths through the method must return a String. Have one return statement that covers both if statements is an efficient way to do so.

Just be sure that you are covering all the possible cases. what if obj is neither a String nor a BlogPost? Usually when you use an if statement you will have an accompanying else statement to cover all the remaining cases.

Thank you Josh :)

Thanks Josh, I used that code and it really helped!

Josh Gold
Josh Gold
12,207 Points

You're welcome.

Nelson Fleig
Nelson Fleig
23,674 Points

This was a tricky one. The good thing is I thing I kinda get it now! Agree on other comments that this lesson could be revamped. It seems type conversion is a very important topic and I don't think this video makes it really clear what it does or when you would do something like this. Maybe spread it over 2-3 lessons?

David Dooley
David Dooley
3,028 Points

^I agree with this

Very tricky. My solution is as follows:

import com.example.BlogPost;
public class TypeCastChecker {

  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 = "";
    BlogPost nowa;
    if (obj instanceof String) {
      result = (String) obj;
    } else if (obj instanceof BlogPost) {
      nowa = (BlogPost) obj;
      result = nowa.getTitle();
    }
    return result;
  }
}

Hi there,

You have added one piece of complexity that isn't required. The challenge says that the method will be passed a String or a BlogPost so you only need to test for one of those outcomes as there are only two possible inputs. I mean if(obj instanceof String) returns false, then obj is a BlogPost as it is not a String. Only those two things will be received.

This means there's no need to test else if as you know that where code reaches the else part of the if conditional, the obj must be a BlogPost. So the ```else part can be:

} else {
  result = ((BlogPost) obj).getTitle();
}

That also removes the need for a temporary local variable - just cast it and call the method on the cast obj

Steve.

For some reason this example "works" for my head. I was having trouble wrapping my mind around all the obj and strings and catching and what not. I can "read" this though. Thanks for sharing.

Yes, but in reality when method will be pass something different than String or BlogPost this program will finish with error because is forced to cast to BlogSpot. In my solution, if other kind of object will be passed (which cannot be cast to BlogSpot method) method returns empty String. What is more we are (I am - I am sure of it) on the beginning the path "Java programmer" so using so fast "chaining calling methods" is not obligated - it is very confusing for beginners.

I agree that chaining methods can look confusing, yes. I prefer it; many other steer away from it. It's a question of choice but sometimes the overhead of additional lines needs to be considered. There's no overhead here so that's not a justification for it! :smile:

However, the reality here is that this method has one single responsibility - as all methods should (aspire to). It is not the responsibility of this method, or the person writing it, to catch every eventuality - the instructions are very clear; The method getTitleFromObject will be called and passed a String and/or a com.example.BlogPost

Trying to catch other eventualities doesn't, in fact, add any clarity. It moves the problem. What if whoever receives the output from this method, the returned String, is looking for a case where this String is empty? What if that's what triggers something magical in the code downstream of this method? Can the receiver of an empty string guarantee that they received an empty String because obj was an empty String? No. In fact, if the input to getTitleFromObject is so lax as to allow any type of object to be passed to it, the recipient of an empty String is actually faced with a position where, mathematically, obj probably wasn't an empty String it could have been anything other than a String or a BlogPost. So, in reality, adding this additional code, not relying on upstream control of what is being sent to getTitleFromObject, makes this method near useless.

We must rely on the upstream control expressly stated in the instructions. Not to do so is to erode the usefulness of the method as the likely output makes the upstream input invisible. Without control, the output of this method is likely to be an empty string which tells us nothing about what obj was in the first place. What was the method supposed to do? Yes, tell us what obj was and handle that to return the appropriate String; that output can be empty, but only if obj was an empty String or the BlogPost's title was an empty String. If we have no control of the input obj the receipt of an empty String tells us nothing about obj.

I hope that makes sense.

Steve.

Hi, thx for this comprehensive response. Now that make sense. But you must admit that, Craig have used to much English in English in that "job to do" description. I mean it was hard for non native English students infer the true meaining of the task. The second part of the assignment went beyond the knowledge conveyed in the film.

Mariusz :)

Agree that the language here is difficult. If it was written in anything other than English, I wouldn't know if was even about Java! :smile: And, yes, this challenge did require some lateral thinking, rather than just relying on the videos. It's all learning! :+1: