gpt4 book ai didi

java - 为什么这段代码在包装在通用函数中时不起作用?

转载 作者:行者123 更新时间:2023-11-30 06:46:08 25 4
gpt4 key购买 nike

我使用此代码执行 HTTP POST 请求并反序列化返回值:

ParameterizedTypeReference<MyClass> typeRef = new ParameterizedTypeReference<>() {};
HttpEntity<Object> requestEntity = new HttpEntity<>("some text");
ResponseEntity<MyClass> result = restTemplate.exchange("/test", HttpMethod.POST, requestEntity, typeRef);
MyClass returnValue = result.getBody();

为了更容易使用,我尝试将代码包装在一个函数中,如下所示:

public <T> T post(Object content, Class<T> returnType, String url){
ParameterizedTypeReference<T> typeRef = new ParameterizedTypeReference<>() {};
HttpEntity<Object> requestEntity = new HttpEntity<>(content);
ResponseEntity<T> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, typeRef);
return response.getBody();
}

但是,代码在放入函数中时会停止运行。它抛出 java.lang.ClassCastException: java.base/java.util.LinkedHashMap cannot be cast to client.rest.MyClass。似乎某些类型信息在此过程中丢失了。

以下是 2 个测试用例形式的完整代码:

package client.rest;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.test.web.client.MockRestServiceServer;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.client.support.RestGatewaySupport;

import static org.springframework.test.web.client.ExpectedCount.times;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;

class MyClass {
public int getInt(){
return 1;
}

public void setInt(int i){}
}

public class TEMP {

public static RestTemplate restTemplate = new RestTemplate();
public static MockRestServiceServer mockServer;

@BeforeClass
public static void beforeClass() throws JsonProcessingException {
MyClass value = new MyClass();

// set up a mock server
RestGatewaySupport gateway = new RestGatewaySupport();
gateway.setRestTemplate(restTemplate);
mockServer = MockRestServiceServer.bindTo(gateway).build();

ObjectMapper objectmapper = new ObjectMapper();
String payload = objectmapper.writeValueAsString(value);

mockServer.expect(times(2), requestTo("/test"))
.andRespond(withSuccess(payload, MediaType.APPLICATION_JSON));
}

@Test
public void without_function() {
ParameterizedTypeReference<MyClass> typeRef = new ParameterizedTypeReference<>() {};
HttpEntity<Object> requestEntity = new HttpEntity<>("some text");
ResponseEntity<MyClass> result = restTemplate.exchange("/test", HttpMethod.POST, requestEntity, typeRef);
MyClass returnValue = result.getBody();
}

public <T> T post(Object content, Class<T> returnType, String url){
ParameterizedTypeReference<T> typeRef = new ParameterizedTypeReference<>() {};
HttpEntity<Object> requestEntity = new HttpEntity<>(content);
ResponseEntity<T> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, typeRef);
return response.getBody();
}

@Test
public void with_function() {
MyClass returnValue = post("some text", MyClass.class, "/test");
}
}

我的问题有两个:

  1. 为什么该功能不起作用?
  2. 我怎样才能让它发挥作用?

最佳答案

1 的答案。

ParameterizedTypeReference<X> typeRef = new ParameterizedTypeReference<X>() {};

感谢最后{} jackson 能够找出什么X然而在运行时使用反射 X在编译时解决,所以如果你有 MyClassT这正是它将在运行时得到的;它无法弄清楚 T 是什么在运行时分配给。

出于同样的原因,如果您继续使用无功能选项但删除了 {}最后它会编译但会导致相同的错误。

回答 2。

而不是 Class<T> returnType ,你永远不会提到顺便说一句,你可以通过 ParameterizedTypeReference<T> typeRef直接地。然后调用该帖子的代码需要确定 T在编译时间:

@Test
public void with_function() {
ParameterizedTypeReference<MyClass> typeRef = new ParameterizedTypeReference<>() {};
MyClass returnValue = post("some text", typeRef, "/test");
}
}

但是我认为您应该考虑不依赖 {} 的替代方案可能有问题的技巧。

你试过了吗ParameterizedTypeReferenceforType ?:

public <T> T post(Object content, Class<T> returnType, String url){
ParameterizedTypeReference<T> typeRef = ParameterizedTypeReference.forType(returnType);
HttpEntity<Object> requestEntity = new HttpEntity<>(content);
ResponseEntity<T> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, typeRef);
return response.getBody();
}

在任何情况下,这都适用于对 T 的非泛型赋值。喜欢MyClass如通过 MyClass.class作为返回类型;它不适用于 ArrayList<MyClass> list; list.getClass()因为它相当于 return ArrayList.class .我想在那些情况下你需要构造并传递一个不同的 Type对应于更复杂类型表达式的实例。

关于java - 为什么这段代码在包装在通用函数中时不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47974703/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com