我有一个返回JSON实体列表的API,例如Gene
,Protein
,Resource
等。例如,Protein
端点返回:
{
next: "/api/1.0/protein?cursor=200",
entities: [
{
symbol: "TARSH_HUMAN",
href: "/api/1.0/protein/TARSH_HUMAN"
},
{
symbol: "ABL1_HUMAN",
href: "/api/1.0/protein/ABL1_HUMAN"
},
...
Resource
端点完全相同,但symbol
为name
除外。
解决方案
我想做的是创建某种EntityListSchema
,无论实体是什么,都可以生成这样的列表。这就是我所拥有的:
public class EntityListSchema<T extends JsonModel> {
private String next;
private List<T> entities;
public EntityListSchema(Class<T> klass, int startAt) {
int nextInt = startAt + Constant.API_MAX_RESULTS;
this.next = "/"
+ Constant.API_URL + "/"
+ klass.getEndpoint() + "?" // <-- This is the problem
+ Constant.API_CURSOR + "=" + nextInt;
}
...
原则上,每个Entity
只能扩展JsonModel
以确保getEndpoint
可用,我们就完成了。但我看到了错误:
类型Class&lt; T&gt;
的方法getEndpoint()未定义
我的理解是发生此错误是因为方法getEndpoint
不是静态的。但如果它是静态的(我使用的是Java 8,那么我可以使用静态接口)我根据类不能返回正确的端点。
有可能实现我想要的吗?这将减少大量的重复代码。
答案 0 :(得分:2)
您会混淆对象实例及其类,例如对于字符串,String.class
是类(您的Class<T>
)而"foobar"
是一个实例(您的T
列表中的元素),在此示例中,只有"foobar"
具有String
方法,String.class
具有Class
方法。
我的建议是在这里使用一些注释来定义“端点”,然后使用Class#getAnnotation
答案 1 :(得分:2)
您在班级的a:hover + .user-image li {
display: block;
}
和Java Class
之间感到困惑,
类是定义。 该类的实例是实现。
Instance
表示Class<T> klass
,它不代表对象Class
或T
的实例,它代表T
本身,带有te变量名,类名称,方法名称,但没有他的实现:
请参阅:Class java
您需要仅使用Class
Class<T>
了解有关java generics
的更多信息这是你的代码:
T
答案 2 :(得分:1)
public EntityListSchema(Class<T> klass, int startAt) {
...
+ klass.getEndpoint()
所以kclass
可以是Gene
,Protein
等。所有Protein
个实例共享相同的endpoint
,因此您想要调用klass.getEndpoint
}。
但是:已清除的Class<T>
类型为Class
,但没有此方法。您真的在寻找一个不存在的 static virtual
方法。
有几种方法可以解决这个问题:registry pattern是一种选择;关于班级的注释是另一个在另一个答案中解释的。
但在您的情况下使用instance method
本身可能最简单,假设您this.next
仅在this.entities
不为空时才需要this.next
。如果您延迟分配getEndpoint
,那么您可以将class JsonModel {
abstract String getEndpoint();
...
}
...
public EntityListSchema(List<T> entities, int startAt) {
this.entities = entities;
if (!entities.empty()) {
int nextInt = startAt + Constant.API_MAX_RESULTS;
this.next = "/"
+ Constant.API_URL + "/"
+ entities.get(0).getEndpoint() + "?" // <-- This is the problem
+ Constant.API_CURSOR + "=" + nextInt;
}
声明为实例方法,并且可以从此列表中的第一个元素中获取其值。或者,您可以使用列表本身进行初始化:
header {
width: 100%;
padding-top: 10px;
padding-right: 10px;
padding-bottom: 10px;
position: fixed;
top: 10px;
left: 0px;
right: 0px;
height: 55px;
border-bottom: 4px solid #636466;
margin-bottom: 10px;
margin-top: 0px;
}
#logo {
float: left;
background-image: url(wordsbyperla_wordpress%20header_small.png);
background-repeat: no-repeat;
height: 50px;
width: 40%;
position: absolute;
margin-top: 24px;
max-width: 411px;
background-size: 100%;
min-width: 300px;
background-position: bottom;
margin-bottom: 10px;
}
nav {
top: 40px;
position: absolute;
right: 3%;
width: auto;
vertical-align: text-bottom;
height: auto;
padding: 0;
font-size: 12px;
}
nav li {
list-style: none;
display: inline-block;
vertical-align: bottom;
height: auto;
top: auto;
}
.menu-item {
text-decoration: none;
list-style: none;
font-family: "Courier";
background-color: transparent;
width: auto;
display: inline-block;
margin-right: 20px;
}
.menu-item a , .menu-item a:visited, .menu-item a:active{
color: #000;
text-decoration: none;
list-style: none;
}
.menu-item a:hover {
color: #EC2726;
}
#searchform {
font-family: "Courier";
border: 1px solid #000000;
margin-bottom: 1px;
background-color: #fff;
}
#s {
border: none;
font-family: "Courier";
margin-top: 0;
margin-right: 0;
margin-bottom: 0;
background-color: transparent;
margin-left: 5px;
}
#searchsubmit {
border: none;
font-family: "Courier";
margin: 0;
background-color: transparent;
}
#contentWrap {
position: absolute;
top: 100px;
right: 0px;
width: 100%;
overflow: auto;
bottom: 50px;
margin-right: 0px;
margin-top: 10px;
margin-left: 0px;
}
.meta {
width: 25%;
position: relative;
font-family: "Courier";
font-size: 12px;
margin-top: 20px;
margin-right: 70%;
margin-left: 0px;
max-width: 200px;
min-width: 100px;
}
.meta div {
text-decoration: none;
text-align: right;
padding-right: 20px;
padding-top: 0px;
}
.meta div a {
text-decoration: none;
color: #000;
}
.meta div a:hover, .meta div a:active {
color: #EC2726;
}
.meta span {
color: #EC2726;
text-transform: lowercase;
}
#tags {
color: #000;
margin-right: 10px;
right: auto;
width: auto;
}
.meta .pagination {
position: fixed;
left: 2%;
font-size: 14px;
font-family: "Courier";
bottom: 35px;
text-decoration: none;
max-width: 200px;
vertical-align: middle;
text-align: right;
right: 70%;
width: 23%;
}
.meta .pagination ul {
padding-right: 25px;
}
.meta .pagination li {
display: inline-block;
list-style: none;
text-decoration: none;
font-family: "Courier";
color: #000;
}
.meta .pagination a , .meta .pagination a:visited{
text-decoration: none;
text-align: left;
margin: 0;
color: #000;
}
.meta .pagination a:hover , .meta .pagination a:active {
color: #EC2726;
}
.meta2 {
height: auto;
width: 75%;
margin-left: 21%;
position: relative;
padding-left: 15px;
min-width: 300px;
top: -50px;
}
.meta2 a , .meta2 a:visited {
font-family: "Helvetica Neue";
text-transform: lowercase;
font-style: normal;
font-weight: bolder;
text-decoration: none;
color: #000;
font-size: 18px;
margin-top: 10px;
}
a:hover, a:active, .meta2 a:hover{
color: #EC2726;
}
.entry p {
font-family: Helvetica;
font-size: 12px;
font-style: normal;
font-weight: 200;
margin-bottom: 50px;
margin-top: -15px;
}
footer {
margin-top: 10px;
position: fixed;
bottom: 10px;
width: 100%;
height: 30px;
/* [disabled]background-color: #f7f7f7; */
border-top: 3px inset #636466;
font-family: Courier;
font-size: 10px;
/* [disabled]display: inline; */
left: 0px;
}
footer ul {
float: right;
margin-right: 3%;
/* [disabled]margin-left: 5px; */
display: inline-block;
width: auto;
list-style: none;
}
PS BTW道具用于将端点识别为单个单词,因此将其命名为getEndpoint,而不是getEndPoint。