Cast to Implemented Class
Asked Answered
L

3

1

So, I'm working in Java, Trying to cast a java.sql.ResultSet to my own class MyResultSet

Here is the code: MyResultSet.java

public class MyResultSet implements java.sql.ResultSet{
     //There are a bunch of Implemented Methods here. None of them have any custom code, They are all unchanged. Just didn't want to put huge code in here.
}

The code I'm trying to use to cast it

ResultSet r = getResultSet();
return (MyResultSet)r;

Whenever I run this, I get a "ClassCastException".

Could someone explain to me how to cast to an Implemented Class?..

Louvain answered 19/2, 2013 at 17:29 Comment(11)
What is the return type of getResultSet() ?Impeachable
Well what's getResultSet()?Hames
Probably java.sql.ResultSetAntisthenes
it's java.sql.ResultSet. It's just example code.Louvain
Seems you have to read some theory about classes and inheritance =) You can't cast any class to your implementation in java.Pr
Alright, Well, Thank you all for your help. Is there any other way to do this?.. I'm returning a ResultSet from a PreparedStatement and I'd like it to be my class returned instead of the default java.sql.ResultSet..Louvain
You should create your own Wrapper class (most probably MyresultSet) .Impeachable
@VishalK, how would I do that?Louvain
public class MyResultSet implements java.sql.ResultSet{ private ResultSet thisIsTheWrappedResultSet; }Araucania
It can be done as follows:Create a constructor in MyresultSet class and in that pass the object of ResultSet obtained. Thereafter you can add various property or functionality to the values obtained from that resultSet object according to your convinience.Impeachable
You could get help from this site techrepublic.com/article/… about creating wrapper class.Impeachable
T
3

You cannot cast. The getResultSet() will give you an implementation of java.sql.ResultSet, which is apparently not yours, but belongs to the Java implementation.

If you want to use your methods, you can delegate the calls:

public class MyResultSet implements ResultSet{
private ResultSet orig;
public MyResultSet(ResultSet orig) {
    this.orig = orig;
}

// do delegations, 1000 methods like this
public String getString(int columnIndex) throws SQLException {
    return orig.getString(columnIndex);
}
// your own methods can come here
}

In Eclipse, you can generate the code for delegated methods, don't have to write them one by one. Just create the private field, and do RightClick - Source - Generate Delegate Methods...

This technique is called wrapping. You wrapped the original object into your one, adding extra functionality.

Now you can call:

ResultSet originalresultset = ...;
MyResultSet myresultset = new MyResultSet(originalresultset);
Toiletry answered 19/2, 2013 at 17:40 Comment(0)
A
5

An example of what you are trying to do:

public interface Animal { } // in your case java.sql.ResultSet

public class Dog implements Animal { } // in your case r

public class Cat implements Animal { } // in your case MyResultSet 

Later on

Animal a = getAnimal(); // returns a Dog
Cat c = (Cat) a; // ClassCastException - Can't cast a Dog to a Cat.

You are trying to cast a Dog to a Cat, but that won't work, because a Cat is not a Dog.

Antisthenes answered 19/2, 2013 at 17:39 Comment(2)
@Dukeling: You have my +1 for also proposing a solution.Antisthenes
Thank you for the explanation, That helps a lot. I now know how to use Delegation, And that should solve my problem. Thanks to @GaborSchLouvain
T
3

Yes, getResultSet() returns a class that implements java.sql.ResultSet, but this doesn't mean that you can cast to another class that implements it. That's not how inheritance works.

       ResultSet
       /       \
MyResultSet  What getResultSet returns

When you have a class of a given type, you can only cast it up or down in the inheritance tree, not up, then down in a different direction.

Options:

  • If you know what getResultSet() returns (I mean the class at the lowest level of inheritance), you can have MyResultSet inherit off of that.

  • Have a wrapper class that has a ResultSet member and that calls the applicable method in that member. Something like:

    class MyResultSet
    {
      private ResultSet resultSet;
      public MyResultSet(ResultSet resultSet1) { resultSet = resultSet1; }
      public doSomething() { resultSet.doSomething(); }
    }
    
Ting answered 19/2, 2013 at 17:37 Comment(0)
T
3

You cannot cast. The getResultSet() will give you an implementation of java.sql.ResultSet, which is apparently not yours, but belongs to the Java implementation.

If you want to use your methods, you can delegate the calls:

public class MyResultSet implements ResultSet{
private ResultSet orig;
public MyResultSet(ResultSet orig) {
    this.orig = orig;
}

// do delegations, 1000 methods like this
public String getString(int columnIndex) throws SQLException {
    return orig.getString(columnIndex);
}
// your own methods can come here
}

In Eclipse, you can generate the code for delegated methods, don't have to write them one by one. Just create the private field, and do RightClick - Source - Generate Delegate Methods...

This technique is called wrapping. You wrapped the original object into your one, adding extra functionality.

Now you can call:

ResultSet originalresultset = ...;
MyResultSet myresultset = new MyResultSet(originalresultset);
Toiletry answered 19/2, 2013 at 17:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.