请问一下,在实现 spring 的 FactoryBean 时,如何得到类成员方法里某个局部变量的真实类型?

2023-05-21 09:39:14 +08:00
 OldCarMan

rt,代码逻辑大概是这样:

public class MyFactoryBean implements FactoryBean<MyBean> {

    private String myProperty;

    public void setMyProperty(String myProperty) {
        this.myProperty = myProperty;
    }

    @Override
    public MyBean getObject() throws Exception {
        return createBean(); 
    }


    public MyBean createBean(){
    	MyBean myBean = new MyBean();
    	myBean.setProperty(myProperty);
        
        //下面 UserListener 调试时,UserListener 对象的类型是“MyFactoryBean$$Lambda$400/0x0000000800e9b558@4225”
        
	UserListener<User1> userListener=new UserListener<User1>(){
		@Override
		public void active(){
			//doSomething
		}
	};
    	Cache.addUserListener(userListener);
	return myBean;
    }

    @Override
    public Class<?> getObjectType() {
        return MyBean.class;
    }

    @Override
   public boolean isSingleton() {
        return true;
    }
}
MyFactoryBean$$Lambda$400/0x0000000800e9b558@4225

代理对象,请问有什么方式能直接得到该类具体的类型吗?除了把对象类型一并传过去

 Cache.addUserListener(userListener,User1.class);
1531 次点击
所在节点    Java
4 条回复
letsky
2023-05-21 10:33:12 +08:00
试试 Spring 的这个类,https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/ResolvableType.html

```java
private HashMap<Integer, List<String>> myMap;

public void example() {
ResolvableType t = ResolvableType.forField(getClass().getDeclaredField("myMap"));
t.getSuperType(); // AbstractMap<Integer, List<String>>
t.asMap(); // Map<Integer, List<String>>
t.getGeneric(0).resolve(); // Integer
t.getGeneric(1).resolve(); // List
t.getGeneric(1); // List<String>
t.resolveGeneric(1, 0); // String
}
```
luckykev1n
2023-05-21 11:27:18 +08:00
不考虑 spring 的话,可以用反射
public class Main {
public static void main(String[] args) {
UserListener<String> userListener = new UserListener<String>() {};
// 获取实际类型
Class<? extends UserListener> listenerClass = userListener.getClass();

// 获取实际范型
Type[] interfaces = listenerClass.getGenericInterfaces();
Type listenerType = interfaces[0];
ParameterizedType paraType = (ParameterizedType) listenerType;
Type[] actualTypes = paraType.getActualTypeArguments();
Class<?> actualType = (Class<?>) actualTypes[0];

// 打印实际范型
System.out.println(actualType);

}
}
luckykev1n
2023-05-21 11:30:56 +08:00
1 楼的这个 ResolvableType ,其实也是 Spring 基于 java 的反射实现的,
```
public ResolvableType[] getGenerics() {
if (this == NONE) {
return EMPTY_TYPES_ARRAY;
}
if (this.generics == null) {
if (this.type instanceof Class) {
Class<?> typeClass = (Class<?>) this.type;
this.generics = forTypes(SerializableTypeWrapper.forTypeParameters(typeClass), this.variableResolver);
}
else if (this.type instanceof ParameterizedType) {
Type[] actualTypeArguments = ((ParameterizedType) this.type).getActualTypeArguments();
ResolvableType[] generics = new ResolvableType[actualTypeArguments.length];
for (int i = 0; i < actualTypeArguments.length; i++) {
generics[i] = forType(actualTypeArguments[i], this.variableResolver);
}
this.generics = generics;
}
else {
this.generics = resolveType().getGenerics();
}
}
return this.generics;
}
OldCarMan
2023-05-23 01:25:17 +08:00
@letsky 谢谢回复
@luckykev1n 谢谢回复,你 2 楼回复的:
ParameterizedType paraType = (ParameterizedType) listenerType;
类型无法转换( java.lang.ClassCastException: class java.lang.Class cannot be cast to class java.lang.reflect.ParameterizedType )。

1.

2.

3.


可能我没描述好,我说的是,我在另外一个类 Cache.java 里面接收 UserListener 时,无法获取到泛型接口 UserListener<T extends User>相应的泛型 T 类型:
public class Cache{
-----

public static void addUserListener(UserListener<T extends User> userListener){

在这里无法直接获取得到 userListener 的相应的泛型 T 类型

}

-----

}

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/941640

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX