3

two class:

public class BaseDo<K> {
    protected K id;

    public K getId() {
        return id;
    }

    public void setId(K id) {
        this.id = id;
    }
}


public class BeanDo extends BaseDo<Integer> {
    private String beanName;

    public String getBeanName() {
        return beanName;
    }

    public void setBeanName(String beanName) {
        this.beanName = beanName;
    }
}

I want use reflect to implment like this:

BeanDo beanDo = new BeanDo();
beanDo.setId("string here");

Integer type reference String type value.

4
  • 4
    Why on earth would you want to do that? Commented Jun 24, 2010 at 3:10
  • So you want to be able to set an integer to a String? Why not extend BaseDo<String>? Commented Jun 24, 2010 at 3:14
  • @SLasks, it comes to my mind that for an existing piece of code he has a concrete instance of BeanDo and have the only thing he has as id is an string. Probably, because it use to be a int, but somebody thought it would be fun if they add an extra identifier in the string: 12345-N ( N for normal ) ... OMG I think I have been through this in the past ... :-S :-S Commented Jun 24, 2010 at 3:23
  • I agree with SLaks - this doesn't make much sense without any context. Others suggested using hashCode(), but that doesn't seem right. It depends on the requirements, which are not clear from the question. Commented Jun 25, 2010 at 14:17

5 Answers 5

1

Generics in Java are not used at runtime, so as far as the java runtime is concerned you're ID field is of type Object and so can be set to any value regardless of the generics. That said, doing so is a bad idea since anything assuming the generic contract will fail.

You can set the field by reflection as follows:

BeanDo beanDo = new BeanDo();
Method method = BeanDo.getClass().getMethod("setId", Object.class);
method.invoke(beanDo, "SomeRandomString");

That said, doing this is an extreamly bad idea because any code compile against BeanDo will assume that the id is an integer not a String. So any code like beanDo.getId() will fail with a class cast exception because it's not actually an integer.

Like the other posters, I'm somewhat in the dark about what you're trying to achieve.

Sign up to request clarification or add additional context in comments.

1 Comment

I agree with this - just because you CAN doesn't mean you SHOULD. If you don't have access to every place getId() is called, you can't guarantee that you're not setting yourself up for problems later. If you DO have access to all the uses, you should just change the object to use a String explicitly.
0

Something like this?

public class BaseDo<K> {

  protected K id;

  public K getId() {
    return id;
  }

  public void setId(K id) {
    this.id = id;
  }

}

public class BeanDo extends BaseDo<Integer> { 

  private String beanName;

  public void setId(String id) {
    setId(Integer.parseInt(id));
  }

  public String getBeanName() {
    return beanName;
  }

  public void setBeanName(String beanName) {
    this.beanName = beanName;
  }

}

Now you can use something like this:

BeanDo beanDo = new BeanDo();
beanDo.setId("2");

1 Comment

-1 try it with: beanDo.setId("string here"); Using someString.hashCode() is all that is needed, see my answer.
0

What about this:

BeanDo beando = new BeanDo();
beando.setId("string there".hashCode());

I don't quite get what you mean with "I want to use reflect to implement this" though.

I guess you want something like this:

    BeanDo doer = ... // get it from somewhere
    String id   = ... // get it from somewhere else too. 

    // and you want to set id to the doer bean.
    reflectionMagicSetId( doer, id ); 

And have the method like:

 private void reflectionMagicSetId( BandDo doer, String id ) {
       /// do some magic here? 
 }

If that's what you want, what I give you works perfectly.

 private void reflectionMagicSetId( BandDo doer, String id ) {
     doer.setId( id == null ? 0 : id.hashCode()  );
 }

2 Comments

It doesn't seem right to use String.hashCode() because multiple strings can produce the same hash value. That wouldn't work if it were used as a primary key in a database, for example. Maybe tidus2005 wants to make a compound key with an integer and a string? Impossible to know from the question.
Good point I guess the only resource remaining would be to subclass
0

If you wann use integer then parse the string to integer as it will contain the integer and use that integer in the calling function argument

Comments

0

It seems like a subclass about the only way to be able to set a string, but still guarantee that anyone who's already calling getId() gets the Integer they expect. Something like this:

public class StringBeanDo extends BeanDo {
  private String stringId;

  public String getStringId()
  {
    return stringId;
  }

  public void setId( Integer val )
  {
    super.setId( val );
    stringId = Integer.toString( val );
  }

  public void setId( String str )
  {
    stringId = str;
    super.setId( convertStringToInteger( str )); // Do this however you like.
  }
}

The implementation of convertStringToInteger would be up to you (it'll depend on what this ID is being used for). The key here is that you're maintaining TWO IDs, and keeping them in sync, so that older code can still limp along to some extent.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.