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

Andre Kucharzyk
Andre Kucharzyk
4,479 Points

Why do we need to cast?

Why do we need to cast obj to string and to BlogPost? Isn't 'instanceof' already checking if obj is String or BlogPost?

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

    if (obj instanceof String) {
        result = (String) obj;

    } else if (obj instanceof BlogPost) {

        BlogPost obj1 = (BlogPost) obj;
        result = obj1.getTitle();
    }

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

    if (obj instanceof String) {
            result = (String) obj;

        } else if (obj instanceof BlogPost) {

            BlogPost obj1 = (BlogPost) obj;
            result = obj1.getTitle();
        }

    return result;
  }
}

2 Answers

Yanuar Prakoso
Yanuar Prakoso
15,196 Points

Hi Andre...

Actually instanceOf is only used to checke whether the obj has the characteristic as a String or not. By the characteristic of a String meaning if you use String methods for example: obj.length() then the obj will be able to answer back the length of character that it has. This is important to do this since you will doing a down casting.

Now before we talk about what kind of evil you may get if you have not properly check the obj using the instanceOf method, we need to talk about why we need to cast the obj. As you have probably know from the video all in the Java Object Oriented Programming is an object. Thus Object is the superclass of all other classes including String. Therefore it is okay to instantiate a String type obj to be an Object type class, like so:

String test = "this is a test";
Object obj = test; //<-- this is up casting

Yes that process is not recommended but it just give you an example how easy it is to push String test into an Object class type called obj since it is the superclass of String.

However, the main downside here is..... Once you up cast test into Object obj you cannot perform or access the methods that usually available for String although you have mentioned that basically obj = test.

Therefore if you try to find out how many characters is in test.length(); it will return an int of 14 characters. However, when you try to do the same thing with obj.length(); Guess what you get? You will get Runtime error of incompatible types. This is because Java does not recognize such method called .length() inside Object class. But you know obj is and Object and also a String. So how you gonna tell Java that it is okay to implement .length() method to it? Well this is where down casting will play a big role.

You need to down cast obj first just like what you have done in the challenge:

String obj1 = (String) obj;//<-- this is down casting
//then you can access the .length() method from the String Class to obj1
int numberOfCharacters = obj1.length();

By doing down casting you practically tells Java that you guarantee that obj is a String and you are ready to face any consequences from implementing any String methods into it. However, run time error is sure is a risky business since this is a major error that hard to catch. How do you make sure that obj is actually a String to avoid getting served a runtime error by Java? That's the job of instanceOf like I mentioned above.

When you do: (obj instance of String) and it returns TRUE meaning it has all characteristics of a String Class meaning it has all attributes and methods generally attached to a String. Therefore, if you down cast obj from Object to String everything will works just fine and you can access all methods provided for all String object. Vice versa if it turns out to be FALSE.

I hope this can help a little

PS: As for Jeff Wilton's answer about instaceOf, yes I myself will not recommend using instanceOf if there is an option using polymorphism. However, in the real world sometimes you cannot get to choose what kind of data other developers pass to your code. There might be cases that data were sent in form of parent classes (often in a form of a list or an array) and then our class need to classify them according to child class. That is why you need instanceOf to check them all and use casting in the most appropriate way. If you can instantiate new object within your class you better use polymorphism but if you had to accept arguments and parameters and classify them according to child classes you need to have instanceOf and Casting.

Andre Kucharzyk
Andre Kucharzyk
4,479 Points

Hello Yanuar!

I appreciate your comprehensive answer. Thanks to you I finally get it.

Jeff Wilton
Jeff Wilton
16,646 Points

The short answer is that instanceof simply returns a true or false value. It doesn't do anything fancy like register a variable as a specific type. The long answer is that instanceof is easy to use incorrectly, and can produce misleading results, and in actual Java practice should be used with extreme care and caution.

As an example: http://www.javapractices.com/topic/TopicAction.do?Id=31

Andre Kucharzyk
Andre Kucharzyk
4,479 Points

Sorry, but I still don't get it. Isnt the fact that if program gets to this line of code:

if (obj instanceof String) { result = (String) obj <-------------------------

isnt it synonymous with the fact that object is of type String?