[Solved] TileEntity.getType() not working for me

I have a problem with the TileEntity:getType() function. It’s described here (https://docs.spongepowered.org/en/plugin/basics/blocks/tileentities.html), but it isn’t working for me. If i call getType() on a TileEntity eclipse says, that this method is not defined.

My Code:

    @Subscribe
    public void onPlayerInteractBlock (PlayerInteractBlockEvent event) {
        if (event.getInteractionType().getName() == "USE" ){
            Optional<TileEntity> clickedEntity = event.getBlock().getTileEntity();
            if(clickedEntity.getType() == TileEntityTypes.SIGN){
                log.info("OMG, it's a sign!");
            }    
        }
    }

Error:

What did I wrong?

if((TileEntity) clickedEntity.getType() == TileEntityTypes.SIGN){

So you only need to cast? I though with Optionals you need to do
clickedEntity.get().getType()

3 Likes

Thank you^^ I’m new in Java.

This thread is such a train-wreck…

@Subscribe
public void onPlayerInteractBlock (PlayerInteractBlockEvent event) {
  // use .equals() not ==
  if (event.getInteractionType().getName().equals("USE")) {
    Location block = event.getBlock();
    if (block.hasTileEntity()) {
      // the get() is finally safe here since we know it's supposed to exist
      TileEntity clickedEntity = block.getTileEntity().get();
      // once again use .equals() not ==
      if (clickedEntity.getType().equals(TileEntityTypes.SIGN)) {
        log.info("OMG, it's a sign!");
      }
    }
  }
}

EDIT: Let me explain why this way is the “most correct” way:

  1. The entire point of using optionals is in wrapping return values that have a chance at not existing. Calling get() is unsafe unless you are sure that the optional exists. Given that not every clicked block has a tile entity, I would say that this is an unsafe assumption.

  2. However, to make life easier there are some convenience methods like hasTileEntity() that do this checking for us. So after we check that, we know for certain that we can call get() on the optional in order to retrieve the value that it is wrapping.

  3. The == operator checks for object identity (when used on objects and not primitives) and the equals() method checks for object equality. What’s the difference? Well, when we instantiate two objects with the exact same fields and from the same class, references to these objects don’t necessarily point to the same place in memory. The two objects have a different identity (meaning == will return false). However if the equals() method is good enough, then it will check the properties of the objects and not their identity.

  4. (TileEntity) clickedEntity.getType() casts the eventual return type, not the entity itself. The “proper” way to do this would be ((TileEntity clickedEntity).getType())

  5. Just casting things is NOT A SOLUTION if the types you have are not the types you want or need. In strongly typed languages such as Java, types actually mean something! Casting by definition ignores this meaning because the programmer believes they know something else about an object. Be careful with your casts, because casting an Optional<TileEntity> to a TileEntity makes absolutely no sense.

11 Likes