以下代码摘自Oracle泛型文档-
class Node<T> {
public T data;
public Node(T data) { this.data = data; }
public void setData(T data) {
System.out.println("Node.setData");
this.data = data;
}
}
class MyNode extends Node<Integer> {
public MyNode(Integer data) { super(data); }
public void setData(Integer data) {
System.out.println("MyNode.setData");
super.setData(data);
}
public static void main(String[] args) {
MyNode mn = new MyNode(5);
Node n = mn; // A raw type - compiler throws an unchecked warning
n.setData("Hello");
Integer x = mn.data; // Causes a ClassCastException to be thrown.
}
}
我对这段代码的理解-
问-方法setData
被覆盖还是重载?
我的立场-由于MyNode
正在扩展Node<Integer>
,因此类型参数T
的值设置为Integer
。
因此类Node
的方法setData(Integer data)
为T = Integer
类MyNode
具有方法setData(Integer data)
。
覆盖,因为签名相同。
Q-即使擦除后,setData方法仍被覆盖吗? 我的理解-
在我们擦除<T>
之后,set方法变成Node
,变成setData(Object data)
,Mynode
的设置方法将为-setData(Integer data)
,因为没有类型参数,也没有要删除的内容。
但这是超载。
问-我们要重载还是覆盖?
我的理解-通过擦除前定义的方法的外观,我们要覆盖。
问-那么如何在擦除后实现覆盖?
我的理解-通过桥接方法。例如:
setData(Object data){
setData((Integer) Data);
}
我的理解正确吗?
此外,class MyNode extends Node<Integer>
何时传递给Integer
?什么时候叫super?
答案 0 :(得分:1)
// declare variable outside document.ready
var plot1;
var storedData;
var drawWithNoDataIndicator = true;
var updateId = 0;
var updates = [
[ ['Take home pay', 44228.33], ['Tax', 8771.67], ['Super', 4162.5 ], ['Regular expenses', 0 ], ['Unallocated', 44228.33], ['Testing', 8000] ],
[ ['Take home pay', 14228.33], ['Tax', 18771.67], ['Super', 14162.5 ], ['Regular expenses', 0 ], ['Unallocated', 44228.33], ['Testing', 8000] ],
[],
];
function getNextUpdate() {
var data = updates[updateId];
updateId++;
if(updateId >= updates.length)
updateId = 0;
return data;
}
$(document).ready(function () {
//jQuery.jqplot.config.enablePlugins = false;
plot1 = $.jqplot('myChart', [''], {
seriesDefaults: {
renderer: $.jqplot.PieRenderer,
rendererOptions: {
showDataLabels: true,
}
},
noDataIndicator: {
show: drawWithNoDataIndicator,
indicator: 'Loading Data...',
},
legend: { show: true, location: 'e' }
});
$('#updateGraph').click(function(){updateGraph();});
$('#redrawGraph').click(function(){redrawGraph();});
});
function updateGraph() {
plot1.destroy();
plot1.series[0].data = getNextUpdate();
if(plot1.series[0].data.length === 0) {
plot1.noDataIndicator = { show: true, indicator: 'No data in the selected set.' };
} else {
plot1.noDataIndicator = { show: false };
}
plot1.replot(true);
}
function redrawGraph() {
plot1.destroy();
$('#myChart').empty();
plot1 = $.jqplot('myChart', drawWithNoDataIndicator ? [''] : updates[updateId], {
seriesDefaults: {
renderer: $.jqplot.PieRenderer,
rendererOptions: {
showDataLabels: true,
}
},
noDataIndicator: {
show: drawWithNoDataIndicator,
indicator: 'Loading Data...',
},
legend: { show: true, location: 'e' }
});
drawWithNoDataIndicator = !drawWithNoDataIndicator;
}
被覆盖。从用户的角度来看,好像setData
被setData(T data)
覆盖,即,当您调用setData(Integer i)
时,它将打印带有< em>“ MyNode” ,而不是“ Node” 。
在类型擦除方法签名的级别上,这将通过添加到setData(42)
的合成桥接方法setData(Object)
来实现,即,如果用MyNode
反编译MyNode.class
,您将看到两个方法:
javap
语言规范说“ override” ,我不知道为什么有人会想要其他东西。
“ <擦除后实现覆盖” 的含义不明确。类型擦除是在类型检查并确定哪些优先于什么之后进行的。没有什么可以“实现”的,而仅仅是工作的顺序(另请参见this comment)。覆盖原始 public void setData(java.lang.Integer);
public void setData(java.lang.Object);
的综合桥接方法看起来像您所写的内容(最多为小错别字):
setData(Object)
至少是the documentation says。但这是一个 synthetic 方法,它是由编译器自动生成的。如果它出现在源代码中,则会给您带来编译错误。