为什么我能够将Long传递给未在Longs上键入的Map.get()方法

时间:2013-11-25 16:40:19

标签: java generics

我在仿制药中遇到了一些时髦的行为,我想知道是否有人可以解释为什么会发生这种情况。首先,我有一个类Foo,它有一个字段ID。 hashCode上的Foo方法只返回id。在另一个课程中,我创建了一个Map<Foo, Double> bar = new HashMap<Foo, Double()

然后,在代码的后面部分,奇怪的开始,我能够做到以下(在这里简化):

Long baz = new Long(1);
bar.get(baz);

所以,我的问题是,为什么编译器没有捕获并将其报告为错误?

编辑:我在最初的问题中犯了一个错误,get是有效的方法,而不是put。我已在下面发布了完整的代码。

Map<WebPage, Double> scoresForPhrase = new HashMap<WebPage, Double>();

// Now that we have a list of matching docs, we can calculate the
// Score of each word in the phrase for each document
for (String term: phrase.getWords()) {
TreeSet<Posting> wordPostings = wordMap.get(term);

    for(Long doc: matchingDocs) {
        if (docDenomScores.get(doc) == null) {
            docDenomScores.put(doc, getDocTotal(doc));
        }

        // The set is of postings, which are compared by docId, so
        // we need a temporary one to enable searching
        Posting temp = new Posting(doc, new ArrayList<Integer>());
        Posting wordPosting = wordPostings.ceiling(temp);
        WebPage page = (WebPage) mWebpageDb
                .getPageIdToWebPageTable().get(doc);

        score = getTermScore(wordPosting, page,
            wordPostings.size());
        score = score * queryTermWeights.get(term);
        Double curScore = scoresForPhrase.get(doc);
    }
}

至于Foo类,它是:

public class WebPage实现Serializable {

private static final long serialVersionUID = -4907557806357281837L;

private String mUrl;
private int mMaxTf;
private long mPageId;
private long mLastTimeUpdated;
private List<Long> mParentIds;
private long mContentLength;
private String mTitle;
private List<Long> mChildren;
private List<String> mAllUrls;

public WebPage(String url, long pageId, long lastTimeUpdated,
        List<Long> parentIds, long contentLength, String title, List<Long> children,
        List<String> allUrls) {
    super();
    this.mUrl = url;
    this.mPageId = pageId;
    this.mLastTimeUpdated = lastTimeUpdated;
    this.mParentIds = parentIds;
    this.mContentLength = contentLength;
    this.mTitle = title;
    this.mChildren = children;
    this.mAllUrls = allUrls;
    this.mMaxTf = 0;
}

public void setUrl(String mUrl) {
    this.mUrl = mUrl;
}

public void setPageId(int mPageId) {
    this.mPageId = mPageId;
}

public void setLastTimeUpdated(long mLastTimeUpdated) {
    this.mLastTimeUpdated = mLastTimeUpdated;
}

public void setParentIds(List<Long> mParentId) {
    this.mParentIds = mParentId;
}

public void setContentLength(long mContentLength) {
    this.mContentLength = mContentLength;
}

public void setChildren(List<Long> mChildren) {
    this.mChildren = mChildren;
}

public void setAllUrls(List<String> allUrls) {
    this.mAllUrls = allUrls;
}

public void setMaxTf(int newTf) {
    this.mMaxTf = newTf;
}

public String getUrl() {
    return mUrl;
}

public long getPageId() {
    return mPageId;
}

public long getLastTimeUpdated() {
    return mLastTimeUpdated;
}

public List<Long> getParentIds() {
    return mParentIds;
}

public long getContentLength() {
    return mContentLength;
}

public List<Long> getChildren() {
    return mChildren;
}

public String getTitle() {
    return mTitle;
}

public List<String> getAllUrls() {
    return mAllUrls;
}

public int getMaxTf() {
    return mMaxTf;
}

@Override
public boolean equals(Object o) {
    if (!(o instanceof WebPage)) {
        return false;
    } else {
        return ((WebPage)o).mPageId == mPageId;
    }
}

@Override
public int hashCode() {
    return (int)mPageId;
}

public String toString() {
    return mUrl;
}
}

2 个答案:

答案 0 :(得分:3)

所以有两件事。首先,请记住,由于类型擦除,没有运行时检查泛型类型。 Map<Foo, Double>只会成为Map<Object, Object>

其次,关于编译器警告或错误,如果bar 声明类型为Map<Foo, Double>,则应收到警告或错误。但如果声明Map,则不会出现警告或错误。我的猜测是bar定义为Map bar

<强>更新

get上没有错误的原因是,根据定义getObject不是通用类型。这是界面的一个奇怪的事情。

Map.get

答案 1 :(得分:0)

您的Map<Foo, Double>可能已投放到Map

Map<Foo, Double> barOriginal = new HashMap<Foo, Double();

// ...

Map bar = barOriginal;

// ...

Long baz = new Long(1);
bar.put(baz, new Double(1));