如何使用 Java 中的 “.class” 从 Class 对象中获取原始类类型?

huangapple go评论55阅读模式
英文:

How to get original Class type from Class object using ".class" in java?

问题

作为抽象的通用 API 函数的一部分,我在构造函数中包括了一个 "Class" 类型的参数,用于将响应(以 JSON 格式)反序列化为该类类型的对象。每个 API 调用可以具有不同的响应类。

目前,我的父类定义如下:

public class MyRequest {
    private int method;
    private String url;
    private Class responseClass;
    private @Setter JSONObject params;

    public MyRequest(int method, String url, Class responseClass) {
        this.method = method;
        this.url = url;
        this.responseClass = responseClass;
    }

    public void executeRequest() {
        new HttpJsonRequest(method, url, params) {
            @Override
            public void handleResponse(JSONObject response) {
                Object responseObj = new Gson().fromJson(String.valueOf(response), responseClass);
                onSuccess(responseObj);
            }
            // ...
        }
    }

    public void onSuccess(Object response) {
        // ...
    }
}

扩展此类的示例 API 请求如下:

public class ExampleRequest extends MyRequest {
    public ExampleRequest(String exampleParam) {
        super(Request.Method.POST, "/example", MyResponse.class);
        JSONObject params = new JSONObject();
        params.put("exampleParam", exampleParam);
        setParams(params);
        executeRequest();
    }
}

具有基本响应类的示例:

@AllArgsConstructor
@NoArgsConstructor
public class MyResponse {
    private @Getter @Setter String StatusCode;
}

要使用上述 API 类,我重写了 onSuccess 方法,该方法返回通用对象并在继续之前将其转换回 responseClass,例如:

new ExampleRequest("exampleParamValue") {
    @Override
    public void onSuccess(Object response) {
        String StatusCode = ((MyResponse) response).getStatusCode();
        // ...
    }
}

有没有办法修改 MyRequest,以便 responseObj 不再是 "Object" 类型,而是构造函数中传递的类类型?我希望避免在每次使用 onSucccess 覆盖时都需要执行从 Object 到该类的强制转换。

英文:

As part of an abstract generic API function, I include a parameter of type "Class" in the constructor which is used to deserialise a response (in JSON format) into an object of that class type.
Each API call can have a different response class.

Currently, my parent class definition is:

public MyRequest {

	private int method;
	private String url;
	private Class responseClass;
	
	private @Setter JSONObject params;

	public MyRequest(int method, String url, Class responseClass){
		this.method = method;
		this.url = url;
		this.responseClass = responseClass;
	}
	
	public void executeRequest(){
		new HttpJsonRequest(method,url,params) {
			@Override
			public void handleResponse(JSONObject response) {
				Object responseObj = new Gson().fromJson(String.valueOf(response), responseClass);
				onSuccess(responseObj);
			}
			...
		}
	}
	
	public void onSuccess(Object response){}
	...
}

An example API request that extends this:

public class ExampleRequest extends MyRequest {

	public ExampleRequest(String exampleParam){
		super(Request.Method.POST, "/example", MyResponse.class);
		JSONObject params = new JSONObject();
		params.put("exampleParam",exampleParam);
		setParams(params);
		executeRequest();
	}
	
}

with basic response class:

@AllArgsConstructor
@NoArgsConstructor
public MyResponse {
	private @Getter @Setter String StatusCode;
}

To use the above API class, I am overriding the onSuccess method which returns the Generic object and casting it back to the responseClass before proceeding, e.g.:

new ExampleRequest("exampleParamValue"){
	@Override
	public void onSuccess(Object response){
		String StatusCode = ((MyResponse) response).getStatusCode(); 
		...
	}
}

Is there a way to amend MyRequest so that instead of responseObj being of class "Object", it can be of whatever class was passed into the constructor?
I'd like to avoid having to perform the cast from Object to this class in every onSucccess override I use.

答案1

得分: 1

你可以通过使 MyRequest 成为泛型类来解决这个问题,为响应类型添加一个类型参数:

import com.google.gson.Gson;
import lombok.Setter;
import org.json.JSONObject;

public class MyRequest<R> {
    private int method;
    private String url;
    private Class<R> responseClass;

    private @Setter JSONObject params;

    public MyRequest(int method, String url, Class<R> responseClass) {
        this.method = method;
        this.url = url;
        this.responseClass = responseClass;
    }

    public void executeRequest() {
        new HttpJsonRequest(method, url, params) {
            @Override
            public void handleResponse(JSONObject response) {
                R responseObj = new Gson().fromJson(String.valueOf(response), responseClass);
                onSuccess(responseObj);
            }
        };
    }

    public void onSuccess(R response) {
    }
}

然后,ExampleRequest 将指定 MyResponse 作为参数的值:

public class ExampleRequest extends MyRequest<MyResponse> {
   // ... 不需要其他改变
}

在实现 onSuccess 时,就不再需要进行强制转换:

new ExampleRequest("exampleParamValue") {
    @Override
    public void onSuccess(MyResponse response) {
        String StatusCode = response.getStatusCode();
    }
};
英文:

You can solve this by making MyRequest generic, with a type parameter for the response type:

import com.google.gson.Gson;
import lombok.Setter;
import org.json.JSONObject;

public class MyRequest&lt;R&gt; {
    private int method;
    private String url;
    private Class&lt;R&gt; responseClass;

    private @Setter JSONObject params;

    public MyRequest(int method, String url, Class&lt;R&gt; responseClass) {
        this.method = method;
        this.url = url;
        this.responseClass = responseClass;
    }

    public void executeRequest() {
        new HttpJsonRequest(method, url, params) {
            @Override
            public void handleResponse(JSONObject response) {
                R responseObj = new Gson().fromJson(String.valueOf(response), responseClass);
                onSuccess(responseObj);
            }
        };
    }

    public void onSuccess(R response) {
    }
}

Then, ExampleRequest would specify MyResponse as the value of the parameter:

public class ExampleRequest extends MyRequest&lt;MyResponse&gt; {
   // ... no other changes
}

The cast is then no longer required when implementing onSuccess:

new ExampleRequest(&quot;exampleParamValue&quot;){
    @Override
    public void onSuccess(MyResponse response){
        String StatusCode = response.getStatusCode();
    }
};

huangapple
  • 本文由 发表于 2023年2月20日 00:02:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/75501453.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定