เปลี่ยนชื่อของการนำเข้าใน Java หรือนำเข้าสองชั้นด้วยชื่อเดียวกัน


363

ใน Python คุณสามารถทำสิ่งต่อไปนี้

from a import b as c

คุณจะทำสิ่งนี้ใน Java ได้อย่างไรเนื่องจากฉันมีการนำเข้าสองรายการที่กระทบกัน


19
ฉันหวังว่าจาวาทำสิ่งนี้ นำไปสู่การเรียนที่มีชื่อที่น่าอึดอัดใจ
fncomp

2
@fncomp: .. และรหัสยุ่งกับชื่อคลาสที่ผ่านการรับรองจำนวนมาก: P
Superole

2
Java 12 ยังไม่มีสิ่งนี้
Janac Meena

คำตอบ:


463

ไม่มีกลไกการสร้างสมนามการนำเข้าใน Java คุณไม่สามารถอิมพอร์ตสองคลาสที่มีชื่อเดียวกันและใช้ทั้งสองคลาสโดยไม่มีเงื่อนไข

นำเข้าชั้นหนึ่งและใช้ชื่อที่ผ่านการรับรองสำหรับอีกชั้นหนึ่งเช่น

import com.text.Formatter;

private Formatter textFormatter;
private com.json.Formatter jsonFormatter;

16
นั่นเป็นคำตอบที่ถูกต้องและสำหรับฉันจะเพิ่มเฉพาะสิ่งที่คุณบอกเป็นนัย: ไม่ไม่มีไวยากรณ์นามแฝงดังกล่าวใน Java
Sean Owen

19
นี่เป็นข้อ จำกัด ใน Java 8 หรือไม่?
HairOfTheDog

8
@HairOfTheDog Nope ขออภัยไม่มีการเพิ่มนามแฝงนำเข้าใน Java8
AdrieanKhisbe

12
ใช่ฉันเห็นด้วยกับความคิดเห็นของคุณ linuxdan ... Java ได้ไปทางไดโนเสาร์ในแง่ของการปรับปรุงไวยากรณ์
Kevin Parker

6
@Bozho import [fully-qualified-name] as [ident]หลามวิธีที่ไม่: “การเป็น” คำหลักที่ดูเหมือนจะไม่เหมาะสมใน Java เช่นเดียวกับทางเลือกที่จะอยู่ที่ประมาณสิ่งที่ C # import [ident] = [fully-qualified-name]ใช้:
Daniel H

60

ตามคำตอบอื่น ๆ ที่ระบุไว้แล้ว Java ไม่ได้ให้คุณสมบัตินี้

การดำเนินงานของคุณลักษณะนี้ได้รับการร้องขอหลายครั้งเช่นเป็นJDK-4194542: ชื่อชั้น aliasingหรือJDK-4214789: ขยายการนำเข้าจะอนุญาตให้เปลี่ยนชื่อจากประเภทที่นำเข้า

จากความคิดเห็นที่:

นี่ไม่ใช่คำขอที่ไม่สมเหตุสมผล แต่ไม่จำเป็น การใช้ชื่อที่ผ่านการรับรองเป็นครั้งคราวไม่ได้เป็นภาระที่เกินควร (เว้นแต่ห้องสมุดจะใช้ชื่อธรรมดาที่เหมือนกันทั้งด้านขวาและด้านซ้ายซึ่งเป็นลักษณะที่ไม่ดี)

ไม่ว่าในกรณีใดจะไม่ผ่านราคา / ประสิทธิภาพสำหรับการเปลี่ยนภาษา

ดังนั้นฉันเดาว่าเราจะไม่เห็นฟีเจอร์นี้ใน Java เร็ว ๆ นี้ :-P


15
ว้าว! คุณไม่ได้ล้อเล่นเกี่ยวกับ "ไม่ (... ) ทุกเวลาเร็ว ๆ นี้" ฉันเห็นว่าคำขอคุณลักษณะถูกเลิกใช้โดยไม่มีจุดน้ำตาลเท่าปี 2541! และความพยายามทุกครั้งที่จะเปิดการอภิปรายใหม่ในช่วง 18 ปีที่ผ่านมาเหล่านี้มีการอ้างอิงถึงการตัดสินใจโบราณ ฉันคิดว่ามันจะง่ายกว่าที่จะโน้มน้าวใจผู้พัฒนา IDE ให้ใช้สิ่งนี้เป็นหน้ากากในเครื่องมือแก้ไขมากกว่าที่จะลองใช้ Oracle
Superole

2
การใช้เหตุผลแบบเก่านั้นถูกต้อง แต่ในทางปฏิบัติแล้วการปะทะเหล่านี้ไม่ค่อยเกิดขึ้น
บางครั้ง

14
ฉันไม่เห็นด้วยที่การปะทะเหล่านี้เกิดขึ้นน้อยมาก การวางแนววัตถุสนับสนุนการตั้งชื่อง่าย ๆ ฉันสามารถมีพนักงานระดับจากห้องสมุดสองแห่งที่แยกสิ่งต่าง ๆ กับพนักงาน (ตัวอย่าง)
Andrei Epure

6
@slim " ในทางปฏิบัติการปะทะเหล่านี้ไม่ค่อยเกิดขึ้น " มันไม่ได้เป็นที่ชัดเจนกับผมว่าทำไมสถานการณ์เหล่านี้จะเกิดขึ้นไม่บ่อยใน java (ที่คุณสามารถมี 10.000+ เรียน) มากกว่าในภาษาอื่น ๆ (ที่คุณมักจะมีชั้นเรียนน้อยกว่า) ซึ่งทำสนับสนุน "น้ำตาล" นี้ไวยากรณ์
Alain Pannetier

21
ไม่ถูกต้องอย่างแน่นอน ฉันกำลังเผชิญกับสถานการณ์ที่ง่ายมากซึ่งอาจเป็นเรื่องธรรมดามากและที่น้ำตาล syntactic นี้จะเป็นประโยชน์อย่างมาก การแปลระหว่างแบบจำลองวัตถุที่เกี่ยวข้อง แต่แตกต่างกัน (ใช้ในผลิตภัณฑ์ที่เกี่ยวข้อง แต่แตกต่างกันตามลำดับ) ซึ่งชั้นเรียนส่วนใหญ่ใช้ชื่อเดียวกันร่วมกัน กระบวนการแปลต้องการให้คุณอ้างถึงคลาสทั้งสองในบล็อคโค้ดเดียวกัน ในกรณีเช่นนี้ (ซึ่งต้องเป็นเรื่องธรรมดามาก) Java ทำให้ชีวิตเป็นเรื่องยากมาก เพียงจำนวนการดูในโพสต์นี้ควรบอกคุณเรื่องราว
hrshi1990

59

เป็นที่น่าสังเกตว่าGroovy มีคุณสมบัตินี้ :

import java.util.Calendar
import com.example.Calendar as MyCalendar

MyCalendar myCalendar = new MyCalendar()

15
ใน Scala มันคือ:import com.example.{Calendar => MyCalendar}
pablisco

24
และใน import com.example.Calendar as MyCalendarKotlin:
KevinO

14
ใน PHP คือ: ใช้ com \ example \ Calendar เป็น MyCalendar
matang

19
มันค่อนข้างน่ารำคาญที่จะเห็นว่า (อย่างน้อย) 3 ภาษาที่ใช้ JVM (Groovy, Scala & Kotlin) มีคุณสมบัตินี้ แต่ Java เองยังไม่ ...
Matthias

2
แล้วมีอะไรประมาณclass MyCalendar extends com.example.Calendar {}นี้ มันไม่เหมาะหรือสวย แต่ควรตอบสนองวัตถุประสงค์ส่วนใหญ่สั้นพูดสะท้อน /* import com.example.Calendar as MyCalendar */คุณยังสามารถย่อหน้ากับความคิดเห็นในกรณีที่จำเป็นเช่น
Braden สุดยอด

21

Java ไม่อนุญาตให้คุณทำเช่นนั้น คุณจะต้องอ้างถึงหนึ่งในชั้นเรียนด้วยชื่อที่ผ่านการรับรองโดยสมบูรณ์และนำเข้าอีกชั้นหนึ่งเท่านั้น


8

วันนี้ฉันได้ยื่นร่าง JEP ให้กับ OpenJDK เกี่ยวกับคุณสมบัตินามแฝงนี้ ฉันหวังว่าพวกเขาจะพิจารณาอีกครั้ง

หากคุณสนใจคุณสามารถค้นหาร่าง JEP ได้ที่นี่: https://gist.github.com/cardil/b29a81efd64a09585076fe00e3d34de7


-4

จริงๆแล้วมันเป็นไปได้ที่จะสร้างทางลัดเพื่อให้คุณสามารถใช้ชื่อที่สั้นลงในรหัสของคุณโดยทำสิ่งนี้:

package com.mycompany.installer;
public abstract class ConfigurationReader {
    private static class Implementation extends com.mycompany.installer.implementation.ConfigurationReader {}
    public abstract String getLoaderVirtualClassPath();
    public static QueryServiceConfigurationReader getInstance() {
        return new Implementation();
    }
}

ด้วยวิธีนี้คุณจะต้องระบุชื่อแบบยาวเพียงครั้งเดียวและคุณสามารถมีคลาสที่มีชื่อพิเศษจำนวนมากที่คุณต้องการ

อีกสิ่งหนึ่งที่ฉันชอบเกี่ยวกับรูปแบบนี้คือคุณสามารถตั้งชื่อคลาสการใช้งานเหมือนกับคลาสเบสพื้นฐานและวางไว้ในเนมสเปซที่แตกต่างกัน ที่ไม่เกี่ยวข้องกับรูปแบบการนำเข้า / เปลี่ยนชื่อ


18
นี่เป็นทางออกที่แย่มาก มันล้มเหลวในการจัดการกับสถิตอย่างสมบูรณ์อาจต้องมีการปรับปรุงอย่างต่อเนื่องและไม่ช่วยแก้ไขปัญหา de / อนุกรม (เช่น deserialising จาก xml ผ่าน jaxb)
วิศวกรซอฟต์แวร์
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.