簡體   English   中英

通配符導入Java和Scala中的用法

[英]Wildcard imports usage in Java and Scala

最近我經常聽到“你永遠不應該使用通配符導入”這樣的陳述。 所以我想向社區詢問這個問題。 是否真的永遠不會在Java生產代碼中使用通配符導入,無論如何? 這條規則有例外嗎? 我對您的個人經歷和意見感興趣。 您是否在生產代碼中使用它們並將其推薦給其他人? 你如何使用它們 - 你能推薦最好的方法嗎?

從Scala的角度來看它也很有趣。 Scala也是如此嗎? 或者Scala中的通配符導入應僅用於演示幻燈片和SO答案?

例如,如果您要查看scalaz頁面 ,他們建議使用通配符導入,例如:

import scalaz._
import Scalaz._   

我認為考慮通常使用通配符導入的隱式轉換也很重要。

在Scala中,通配符導入是必須的,因為許多庫期望它們的隱式轉換在范圍內,但它們並不總是方便地命名。 所以,

import collection.JavaConversions._

是一個好主意,而

import collection.JavaConversions.{asJavaConcurrentMap,enumerationAsScalaIterator,...}

令人難以置信的尷尬。 更好的是,在Scala中,您可以將導入放在任何范圍內:

package mypackage {
  class MyClass {
    def myGraphicalWidgetHandler {
      import java.awt._
      ...
    }
    ...
  }
  ...
}

這確實有助於在整個文件中保持命名空間的混亂。 您可以有選擇地重命名您知道會沖突的部分導入:

import java.awt.{List => AwtList, _}

相比之下,在Java中,您僅限於導入的全局范圍,並且您無法重命名它們; 你也沒有隱式轉換,所以只需要提取你正在尋找的東西。 另一方面,您有強大的IDE支持,可以幫助您找到您正在尋找的類,並為您導入它。 所以對於Java來說,有一個合理的論據是你應該讓你的IDE接受你需要的東西,而不是你決定抓住所有東西。 就個人而言,我仍然覺得這太尷尬了,大部分時間都只使用通配符導入。

好吧,通過指定完整的類名,可以消除歧義。 因此,當您明確說明要導入哪個類時,更容易理解代碼的意圖。 Java 1.2也浮現在腦海中:

import java.util.*;
import java.awt.*;

...
List blah;

這在Java 1.1中運行良好。 但是,在Java 1.2中,一個List接口被添加到java.util中,以前的代碼已經不再適用了。 很多開發者都哭了。

在Java中,使用通配符進行導入或非導入主要是代碼可維護性和[不]處理導入歧義的意願(當兩個導入的包具有相同名稱的成員時)。 另一方面,從意識形態的角度來看,導入整個包(例如, java.sql._ )是非常有意義的,你想要具有一致的行為,並避免從同一個包中導入多行。

Scala的大部分內容都是如此,區別在於:

  1. 如果要從同一個類中導入多個成員而不污染代碼,同時避免可能的歧義,Scala為此提供了一種特殊的語法: import java.io.{File, FileInputStream} ;
  2. 在Scala中,您可以為導入的成員提供別名,以處理歧義: import java.lang.{Double=>JDouble} ;
  3. 正如您正確提到的那樣,使用通配符導入會向上下文添加含義,這可能會導致另一種含糊不清的情況(這是思考的另一個原因);

總而言之,IMO,Scala中的通配符導入語法只應在這種情況下使用,當您使用特定的庫並希望它一致行動時(如果是Scalaz,則擁有所有必需的成員,隱式轉換等等)。

對於Java方面:使用通配符導入絕對沒有錯! 在運行時沒有性能缺乏,因為只加載了實際使用的類。

java的導入機制發生在編譯時。 它唯一用於的是如果你在代碼中使用類Date作為例子,在同一個包中沒有類Date ,導入機制將用於在其中一個import語句中查找類Data。

所以它所做的只是“找出你所引用的類”。 什么都不會改變你的運行時性能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM