Maison > Questions et réponses > le corps du texte
问题1:
想写个requestInfo的toString方法,把所有的成员变量都打印出来,子类就不用每次都写个toString方法了,但是父类怎么获取子类成员变量的值?
public class RequestInfo
{
public String toString()
{
StringBuilder sb = new StringBuilder();
Field[] fields = this.getClass().getDeclaredFields();
for(Field field : fields)
{
sb.append(field.getName(), " = ", (这里怎么获取属性值?), ";");
}
return "";
}
}
问题2
下面那个类P怎么实例化,也没懂错误的原因,用P.getClass()还是不行
public abstract class AbstractService<Q extends RequestInfo, P extends ResponseInfo>
{
public static final Logger LOGGER = LoggerFactory.getLogger(AbstractService.class);
private String logTag;
private P respBean;
public P execute(Q reqBean)
{
init();
LOGGER.info(StringUtil.appendStr("Request : {}, req = {}", logTag, reqBean.toString()));
try
{
if (checkInput(reqBean))
{
handle(reqBean, respBean);
}
else
{
throw new Exception(StringUtil.appendStr(logTag, " check input param invalid"));
}
}
catch (Exception e)
{
LOGGER.error(StringUtil.appendStr(logTag, " Exception: "), e);
}
return respBean;
}
protected void init()
{
logTag = getClass().getSimpleName();
respBean =P.class.newInsance();//这里报错,cannot select from a type variable
}
protected boolean checkInput(Q reqBean)
{
return true;
}
protected abstract void handle(Q reqBean, P respBean)
throws Exception;
}
PHPz2017-04-18 10:53:04
Les génériques ont été effacés après la compilation. Le jvm ne peut pas du tout voir les informations génériques. Cela est dû à des raisons historiques, donc le p.getClass que vous avez mentionné ne peut pas exister
.La première question est une bonne idée, mais pour autant que je sache, elle ne peut pas être réalisée. L'objet ne peut pas connaître l'état de la sous-classe. Le mécanisme polymorphe de Java ne peut apprendre que de la classe parent ou de la classe parent. méthodes dans l'interface
Je suppose que la première question est que vous pensez pouvoir obtenir les variables membres d'une sous-classe parce que vous pensez qu'une fois la méthode toString de la sous-classe exécutée après l'héritage, la vôtre sera également appelée. faux. Au moment de l'exécution, le jvm obtiendra cette méthode à partir de l'espace objet de la classe parent et l'exécutera. Par conséquent, quoi qu’il arrive, ce ne sont que des variables membres de la classe parent
J'ai fait une erreur dans la partie en italique ci-dessus. Après avoir exécuté l'EDI pour le tester, j'ai découvert que j'avais tort sur ce que j'avais compris auparavant. J'espère que cela n'a pas causé de problèmes à la personne qui pose la question.
Le code publié ci-dessous peut boucler pour obtenir toutes les variables de la sous-classe à la classe parent. J'espère que cela aide
public String toString() {
StringBuilder sb = new StringBuilder();
Class clazz = this.getClass();
while(clazz.getSuperclass() != null){
Field[] fields = clazz.getDeclaredFields();
try {
for (Field field : fields) {
field.setAccessible(true);
sb.append(field.getName()).append("=").append(field.get(this))
.append("\n");
}
} catch (Exception e) {
e.printStackTrace();
}
clazz = clazz.getSuperclass();
}
return sb.toString();
}
怪我咯2017-04-18 10:53:04
package cn.hylexus.app.util;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class ReflectionUtils {
public static List<Field> getFields(Class<?> clz) {
List<Field> ret = new ArrayList<>();
for (Class<?> c = clz; c != Object.class; c = c.getSuperclass()) {
Field[] fields = c.getDeclaredFields();
ret.addAll(Arrays.asList(fields));
}
return ret;
}
/**
* @param cls
* 子类对应的Class
* @param index
* 子类继承父类时传入的索引,从0开始
* @return
*/
public static Class<?> getSuperClassGenericType(Class<?> cls, int index) {
if (index < 0)
return null;
Type type = cls.getGenericSuperclass();
if (!(type instanceof ParameterizedType))
return null;
ParameterizedType parameterizedType = (ParameterizedType) type;
Type[] typeArguments = parameterizedType.getActualTypeArguments();
if (typeArguments == null || typeArguments.length == 0 || index > typeArguments.length - 1)
return null;
Type t = typeArguments[index];
if (!(t instanceof Class)) {
return null;
}
return (Class<?>) t;
}
public static Class<?> getSuperClassGenericType(Class<?> cls) {
return getSuperClassGenericType(cls, 0);
}
}
public class RequestInfo {
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
//可以拿到多层次基础的属性
List<Field> fields = ReflectionUtils.getFields(this.getClass());
for (Field f : fields) {
f.setAccessible(true);
try {
sb.append(f.getName()).append("=").append(f.get(this)).append("\n");
} catch (Exception e) {
e.printStackTrace();
}
}
return sb.toString();
}
}
@SuppressWarnings("unchecked")
protected void init() {
logTag = getClass().getSimpleName();
try {
//这里可以拿到动态绑定的Class信息
Class<?> clz = ReflectionUtils.getSuperClassGenericType(this.getClass(), 1);
respBean = (P) clz.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
}
怪我咯2017-04-18 10:53:04
Le premier problème peut être résolu en utilisant commons-beanutils.