Java Java Data Structures Getting There Type Casting

Doubts..!!!

In java-repl

  1. Why do we write (Treet) before somestuff in this query..
    ((Treet) someStuff[1]).getDexcription();

  2. I don't understand, when ((Treet) someStuff[1]).getDexcription(); is executed, why does it gives error.. ??

  3. And please tell me if I am on right path here:

When we check : someStuff[0] instanceof Treet--so it checks whether "Example text" is instanceof ("Example Text", craigdennis)"..right ?

And when we check: somestuff[0] instanceof String, what does "String" represent here ?

Help!!! Help!!! It's like a nightmare to be honest... Can't get anything out of it.

Simon Coates
Simon Coates
28,678 Points

String is java.lang.String. Unless you wrote the method to be getDexcription, it's a spelling mistakes (description)

1 Answer

Simon Coates
Simon Coates
28,678 Points

We use instanceof when we're not sure what contained inside. If you know the type, you can cast the object to the appropriate type and then java can be sure that the methods you call of that type exist. (compile time checking). Here's a casting demo:

class Main {
  public static void main(String[] args) {

    Object obj = "this is a string containing x";
    //obj.indexOf("x");               //doesn't pass compile.
    if(obj instanceof String){ //if it's a String
      String objString = (String) obj; 
      //this is the same object, but java now knows it's a string.

      //we can now call String methods on it.
      System.out.println(objString.indexOf("x"));

      System.out.println(((String) obj).indexOf("x")); // also works      
    }    
  }
}
Simon Coates
Simon Coates
28,678 Points

There are situations where you don't know the precise types. testing the type using instanceof means that casting is safe. Once java is told the variable is a type, you can write code that uses it as that type. However, if you don't test using instanceof and cast a variable to an unrelated type, you may get a runtime failure (you'll pass compile tests, but crash when java actually run the thing). You'll find a bunch of explanations on the internet (eg. http://stackoverflow.com/questions/5289393/casting-variables-in-java ).

eg. of code that will crash without using instanceof

import java.util.Date;

class Main {
  public static void main(String[] args) throws Exception {

    Object[] obj = new Object[3];
    obj[0] = "";
    obj[1] = "";
    obj[2] = new Date();

    for(int x = 0; x< 3; x++){
      String y = (String) obj[x]; //this crashes on third loop
      System.out.println("runs");
      y.indexOf("x"); 
    }
  }
}

output:

runs
runs
Exception in thread "main" java.lang.ClassCastException: java.util.Date cannot be cast to java.lang.String
    at Main.main(Main.java:12)
exited with non-zero status

You said : We use instanceof when we're not sure of what's contained inside

So in above demo for e.g.--

Object obj = " firefox";---(So it's a string ..right ?.... Because of " " , then why are we checking if it's a String again ----if(obj instanceof String) ????

And why does this --- obj.indexOf("x"); ------ doesn't pass compile.... because java doesn't know if it's a string ?

Simon Coates
Simon Coates
28,678 Points

it's an artificial example and java isn't very smart. At compile time, it isn't able to work out that obj is only ever a string. Since it's typed as Object (the base class) in the declaration, it can only access methods that exist for the object type. to get string methods you have to tell java 'Hey, it's a string' (the cast). If there is any doubt about the type (often there isn't), then testing what is contained inside is necessary to ensure the cast is safe. (the second code fragment demonstrates what happens when I lie to java about the type. It believes me, attempts the cast and crashes).

Ok.. I get it... with the string methods... but with arrays...??

In the video, Craig Dennis explains--

how in arrays we can run into problem...

So he creates an array of objects Objects[] someStuff = {treet, "a string"}; // Treet = {craigdennis, Example text}

someStuff= {Treet: "Example text" craigdennis , "a string"}

And typecasting it with Treet-- ((Treet) someStuff[0]).getDescription(); the output he gets is "Example text".

And then he does --- ((Treet) someStuff[1]).getDescription(); the error he gets is:

java.lang.ClassCastException: java.lang.String cannot be cast to com.temtreehouse.Treet---- I didn't understand this part..

Why "a string" didn't pop out as an answer..? which is someStuff[1].

Sorry to bother you with such questions..

Simon Coates
Simon Coates
28,678 Points

with((Treet) someStuff[0]), the value at someStuff[0] is a Treet, so casting is saying 'hey that's a Treet'. but with someStuff[1], the value is a string, so when you tell java 'Hey it's a Treet' (what the cast is doing), Java recognises that it isn't and crashes.

Alright. Thanks a lot.

Jonathan Hartmayer
Jonathan Hartmayer
5,579 Points

This was very helpful, thanks!