Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

Java Java Data Structures Getting There Type Casting

Miguel Gonzalez Rocha
Miguel Gonzalez Rocha
2,849 Points

Help with the challenge pls

public static String getTitleFromObject(Object obj)

i dont understand why it takes Object obj if it is no created yet, and as i understand i have to upcast the String but where?

Eric Chan
Eric Chan
4,254 Points

I have read through all the comments but still confused why we have to put at the end of the code:

return "";

I thought the return statements in the if/else if clause already return the String. Why do we need the above code to end the method?

Thanks for your time~

Rob Bridges
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Rob Bridges
Full Stack JavaScript Techdegree Graduate 35,459 Points

Hello,

We need to to add the final return ""; because the method requires that it returns a string. The compiler would state that it's possible that the code within the if and else block might not be reachable, the compiler assumes the possibility exists that both cases would be false, so it would skip over them, and java recognizes that this means that neither of those return values would be reached, so it still requires that we return a string value, which we have to with the return ""; line.

Basically, if we ever see our method returning a blank string we'd know that there was bug, as the item checked was neither a String or BlogPost type object, which we assumed that we were, but let's say that somehow we were checking an item that was an int. It would skip over both tests and instead return ""; which would let us know that we've reached a bug in our program.

To sum it up we return the final ""; string because our method that a string be returned to compile correctly, because the compiler recognizes that it's possible that the return statements never be reached if the conditions are not met, however since a return statement will break out out of any method, as soon as one of those conditions are met, we break out of the method before we return "";

Thanks. hope this helps.

Eric Chan
Eric Chan
4,254 Points

That's very clear explanations! Thanks Rob!

6 Answers

Rob Bridges
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Rob Bridges
Full Stack JavaScript Techdegree Graduate 35,459 Points

Hey there Miguel,

This challenge is when we are first introducted to type casting in a context where we do it ourselves, instead of seeing it, great way to learn. If not frustrating, but it does work.

I broke this down in another question, but I'll try to do the same here.

In the TypeCastChecker.java we have the skeleton code for it.

public static String getTitleFromObject(Object obj) {

    return "";
  }

So first things first, our directions want us to check if the object is an instance of a String and return it as a String if it is. We can do this by the first if statement of

if (obj istanceof String) {
  return (String) obj;
}

Secondly it's wanting us to check to see if the object is an instance of a BlogPost, we just modify our code above and check, but we run into troubles, because it's not sure we're calling getTitle() on a BlogPost object, this is easily remedied by type casting the variable like in the second if statement.

else if (obj instanceof BlogPost) {
      BlogPost myBlogPost = (BlogPost) obj;
      return myBlogPost.getTitle();
    }

After that, your code should look similar to

public static String getTitleFromObject(Object obj) {
    if (obj instanceof String) {
      return (String) obj;
    }
    else if (obj instanceof BlogPost) {
      BlogPost myBlogPost = (BlogPost) obj;
      return myBlogPost.getTitle();
    }
    return "";
  }
}

Thanks, let me know if this clears things up or not.

Miguel Gonzalez Rocha
Miguel Gonzalez Rocha
2,849 Points

well you did gave me the answer but im still confused, im gonna keep watching the videos and if i dont understand with more examples im gonna ask again, thank you for the explanation.

Miguel Gonzalez Rocha
Miguel Gonzalez Rocha
2,849 Points

Can you give an example on how i might need to use it? i understand now what it does but i still cant understand where to use it and why Thanks for the help i really apreciate it :)

Amal Karim
Amal Karim
5,329 Points

I can't understand why we must test whether obj is a String or not. The title of the method is "getTitleFromObject". So if obj is really a String, then we will NOT return a title from obj, we just return that obj. We can erase the first "if", no?

Benjamin Gooch
Benjamin Gooch
20,365 Points

I spend probably 30 minutes trying to figure out the second task. It took me a long time to realize you have to store the obj in a BlogPost variable. I kept trying to call the getTitle() method and it kept telling me it couldn't do it due to it being static.

Frustrating, but I finally got it.

Tim Strand
Tim Strand
22,458 Points

Why does adding the (BlogPost) obj; instead of just obj clear up the compiler error: Object cannot be converted to BlogPost? i dont understand tagging obj with BlogPost since its not coming out of the BlogPost file?

Jacob Martin
Jacob Martin
4,182 Points

Thank you for clearing it up.

Nikita Voloboev
Nikita Voloboev
4,816 Points

I am curious why do you need to convert obj to String with (String) as you have already check that it is of type String?

if (obj istanceof String) {
  return (String) obj;
}
Rob Bridges
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Rob Bridges
Full Stack JavaScript Techdegree Graduate 35,459 Points

Hey there Miguel, the main reason that this would be used would be if we had an arrayList that contained multiple objects like Craig showed in the video. Let's assume it had ints strings and floats. We could use a method like this to determine what the way object was and add it to a new array list that contained just that type. So if it was an int our if statement could create a new array list of just ints and pass that value in. Wed be able to categorize an unknown object array with a method similar to this.

Miguel Gonzalez Rocha
Miguel Gonzalez Rocha
2,849 Points

Thank you i just understood how to use them and why they are usefull with this and the Interfaces video where we use upcasting again. Thanks a lot Rob. Im loving more and more the teamtreehouse community.

You're awesome Rob Bridges keep doing what you're doing :)

Ben Summers
Ben Summers
1,306 Points

Great - thanks Rob ... I get it now.

We have passed an Object into the method, which, because it is a superclass, could be any type of object.

So we have to tell the method this Object is a String object.

Rob Bridges
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Rob Bridges
Full Stack JavaScript Techdegree Graduate 35,459 Points

Exactly,

The method is only seeing that it is an Object, it doesn't know it is a String, even if we check if it's an instance of one, we still need to nudge it in the right direction.

Good job!

Ben Summers
Ben Summers
1,306 Points

I'm still baffled, by both the 'if' tests:

If obj is a String, why do we have to type cast the return value to a (String)? Obj is a String, otherwise this code will not execute.

Similarly, why do we have to execute code that typecasts obj to a BlogPost if that code only executes if obj already is a BlogPost?

Thanks.

Rob Bridges
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Rob Bridges
Full Stack JavaScript Techdegree Graduate 35,459 Points

Hey Ben,

The reason for that is because the method is expecting a string to be returned, and will throw an error otherwise. based on the assumptions that Craig allowed us we knew the object was either a String or a BlogPost object. Since the method required a return of a String, we'd first check to see what object was passed in, if it was a String object we type cast it to String and return it. Without typecasting the object it'd give an incompatible type error.

We had to typecast the object to a blogPost so that we could have a variable to call the getTitle() method on it, which was the method that returns a String on the object, as the method declares that it must be a String.

Let's say we also were told that the object we were checking might also be a int, so we'd have to add that code to our method.

if (obj instanceof int) {
int myInt = (int) obj;
return Integer.toString(myInt);
}

Would have to be added in our code. Basically the whole point of the exercise was dropping us in an event where we were being given unknown objects, Craig simplified it, but wanted us to return type casts the objects to what they properly were, and return the value as a String, as that is what the method was declared to return.

Thanks.

Ben Summers
Ben Summers
1,306 Points

Hi Rob - thanks for the time you have taken but the circularity issue that confuses me is in you answer too:

"if it was a String object we type cast it to String and return it"

Why do we have to typecast an object to String when it already is a String? Why can't we just return the String, which is what the method requires. It appears like an unnecessary step to me.

I know I'm being slow, but I want to make sure I'm following what's going on here.

Thanks.

Rob Bridges
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Rob Bridges
Full Stack JavaScript Techdegree Graduate 35,459 Points

Hey Ben,

I know it sounds like we're definitely spinning wheels on it. but unfortunately computers aren't smart enough to understand "obvious" yet, to us it's obvious that if the Method requires a string be returned, and we check to see if it is a string, than we should just be able to do it. That makes sense to us.

Unfortunately to a computer it does not, they have us aced on logic and math, but as far as practical sense, you have to baby them along.

To a computer here's what it see's, imagine the disagreement below between you and the computer.

I'm passing you a variable.

Check and see if it's an instance of a String.

Okay, great it is.

Return it.

"Wait, we're only supposed to return strings"

I know we just checked, it's a string

"No this is generic Object that is an instance of a String, it's not a String, just a generic object."

This is where it would throw the uncompatiable types error to us.

We have to tell it to turn the generic object that we know is a String into a String to make it happy.

To put it simply, we have to do it so that Java knows completely what we're doing, even if a generic object like the one passed in is an instance of a String, Java will stubbornly stick by the fact that it's just a Generic object until we type cast it.

Only then would Java understand what we're trying to do, and not toss an error.

Hope this helps.

Glen Hayes
Glen Hayes
5,798 Points

Could someone please help me?

I am getting a missing return statement error, line 27 with the following code for the first part of the instanceof challenge.

Does an if statement require as else statement?

thanks

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 getTitleFromObject(Object obj) { if (obj instanceof String) { return (String) obj; }

}

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;
}

}

Tim Strand
Tim Strand
22,458 Points

i believe you have to have a return outside your {} basically right now you are telling it if (true/false) {true do this} "false do this" but you are missing the false return value. which in this case would be return "" or something since if its false you dont want to display anything

aneaswiley
PLUS
aneaswiley
Courses Plus Student 1,612 Points

So Just trying to make sure that I have this down I'm a Visual Person so hopefully this makes sense. Please let me know anyone if I am misdirected on any of this. TypeCasting with Objects from one class to another is something similar to the way Mail works. In its original form we would usually we would write a letter to a friend but we need to have this letter in an envelope. So we write the specific letter according to the letter classification "LETTER" and then mail it off according to the OBJECT classification of which can contain a letter Every body gets mail and knows what an envelope is. Create an "envelope variable and send the letter according to the ENVELOPE classification. The letter holds specific information that we will send to a friend in another CLASS a different part of the world. We then would tell Java - HEY I want to send this letter in the form of a bigger more obscured form OBJECT-->(in the form of an ENVELOPE hence we create an ENVELOPE object "envelope"). When our friend in a different CLASS gets our letter it is still in the (OBJECT)<-- ENVELOPE envelope form.

At that point your friend in the other Class or other end doesn't know that he will be getting a letter from you but he sorts all inbound mail that comes in because he has a mailbox to receive objects. Therefore he should check all mail with instanceof sort statements to see what TYPE of mail he is getting. Because he could be getting different object types that are still considered an object

Then he sees that this is your "letter" TYPE of "envelop" that you sent (or boolean response from the instanceof return).

He (Your Friend in a different class) immediately creates a place to store the letter so that he could read it as it should be in a letter variable from the LETTER class.

Letter letter;

Then he Casts the Envelope TYPE<-- OBJECT into that letter Variable through the letter class. it goes something like: Letter letter; <-- I have a space to store the object that matches the letter type of object that I received letter = (Convert into THE LETTER CLASS) envelope;<--- the actual object that was created when you put the letter inside.

Rob Bridges
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Rob Bridges
Full Stack JavaScript Techdegree Graduate 35,459 Points

Hey there, sounds like you mostly got it I read through what you said and that looked correct.

To use your example, we basically ship our friend multiple things in the mail, he knows that we shipped him something, but until he actually opens his mailbox and looks at each item, he doesn't know what it is until he reaches his hand in and checks (It is at this point that our program would type cast everything based on our code) .

So yes, it sounds like you understand the concept, well done!