Есть ли способ привести к типу с помощью строки - PullRequest
0 голосов
/ 04 ноября 2019

У меня есть строка, которая сообщает мне, к чему я хочу привести мой объект. Есть ли способ привести к этому объекту?

Вот некоторый псевдокод, который определяет, что я хотел бы сделать


public TypeToCastTo Cast(T object, String TypeToCastTo) {
  switch (TypeToCastTo) {
   case "foo":
     return (foo)T;
   case "otherType":
     return (otherType)T;
   ...
  }
}

edit
Я хотел создать игру, в которой я могу нажать на кнопку, чтобы купить что-то, например, меч или доспехи, которые наследуются от worldObject. Я полагаю, что поскольку я могу возвращать класс оружия или доспехов (которые оба наследуют от worldObject), имеет смысл вернуть worldObject и затем уменьшить его до нужного класса (на основе его имени (String)).

edit 2: Как уже упоминалось в комментариях, это проблема XY. Первоначально я пытался создать функцию, которая возвращала бы тип downcast, но на самом деле это не имеет смысла, поскольку в случае его использования где-то еще мне понадобится оператор switch, чтобы определить, что делать с объектом в любом случае (в этот момент я могу разыграть) вместо того, чтобы иметь

public TypeToCastTo Cast(T object, String TypeToCastTo) {
  switch (TypeToCastTo) {
   case "foo":
     return (foo)T;
   ...
  }
}

И используя мою функцию для сотворения WorldObject, я могу получить

Method DoingSomethingWithWorldObject(WorldObject T) {
 switch(T.typeToCastTo) {
  case "foo":
    foo temp = (foo)T;
    // code using temp
  case "other":
    other temp = (other)T;
    // code using temp
  ...
 }
}

, хотя несколько человек упоминали, что, вероятно, это неправильното, как я думал об этом, включая ответ, который я пометил правильно (который ответил на мой вопрос, хотя я задавал неправильный вопрос), причина, по которой я действительно понял это, была из-за удаленного ответа.

Ответы [ 2 ]

0 голосов
/ 04 ноября 2019

Альтернативный подход (хотя я не знаю, считается ли это плохой практикой):

public TypeToCastTo Cast(T object, String TypeToCastTo) {
  switch (TypeToCastTo) {
   case "foo":
     return new Foo(object);
   case "otherType":
     return new OtherType(object);
   ...
  }
}

Вам понадобятся конкретные конструкторы с соответствующими параметрами (перегруженными) для разных типов, к которым вы хотите обратитьсяхотя. Внутри этих конструкторов вы можете контролировать точные «переводы» из одного типа в другой.

0 голосов
/ 04 ноября 2019

Как уже упоминалось в комментариях, вы можете сделать это, используя отражение с методом Class.cast:

public Object cast(Object object, String typeToCastTo) {
  switch (typeToCastTo) {
   case "foo":
     return Foo.class.cast(object);
   case "otherType":
     return OtherType.class.cast(object);
  }
}

Однако тип возвращаемого значения метода должен быть Object, поскольку вы этого не делаетезнать фактический тип возвращаемого значения, закодированный в параметре typeToCastTo.

То есть это имеет смысл по крайней мере, если у вас есть экземпляр Class под рукой:

Class<Foo> fooClass = (Class<Foo>) Thread.currentThread().getContextClassLoader().loadClass("my.foo.Foo");
Foo fooObject = foo.cast(object);

Но все это кажется довольно бессмысленным ...

Судя по комментариям. Чтобы вызвать приватный метод родительского класса, вам не нужно приводить:

Object object = new SubFoo();
Method privateFooMethod = Arrays.asList(ParentFoo.class.getDeclaredMethods())
    .stream().filter(m -> m.getName().equals("privateFooMethod")).findAny()
    .get();
privateFooMethod.setAccessible(true);
privateFooMethod.invoke(object);

Но вам стоит подумать дважды, прежде чем использовать отражение для достижения чего-то подобного. Это очень похоже на плохой дизайн класса / интерфейса, приводящий к странным решениям для довольно простых нужд.

...