Mengimpor dua kelas dengan nama yang sama. Bagaimana cara mengatasinya?


107

Katakanlah saya memiliki kode seperti:

import java.util.Date;
import my.own.Date;

class Test{

  public static void main(String [] args){

    // I want to choose my.own.Date here. How?
    ..
    // I want to choose util.Date here. How ?

  }
}

Haruskah saya menjadi nama kelas dengan kualifikasi penuh? Bisakah saya menghilangkan pernyataan import? Apakah skenario seperti itu biasa terjadi dalam pemrograman dunia nyata?


Bukan jawaban untuk pertanyaan Anda, tetapi di C # Anda dapat menggunakan alias untuk namespace apa pun. Mungkin itu hanya gula sintaksis tetapi sangat membantu: msdn.microsoft.com/en-us/library/7f38zh8x.aspx
borjab

Jawaban:


154

Anda dapat menghilangkan pernyataan import dan merujuknya menggunakan seluruh jalur. Misalnya:

java.util.Date javaDate = new java.util.Date()
my.own.Date myDate = new my.own.Date();

Tetapi saya akan mengatakan bahwa menggunakan dua kelas dengan nama yang sama dan fungsi serupa biasanya bukan ide terbaik kecuali Anda dapat membuatnya benar-benar jelas yang mana.


2
Jika Anda menggunakan Eclipse, Anda dapat mengubah nama your.own.Datemenggunakan ctrl + shift + R. Ini secara otomatis akan mengubahnya di mana pun Anda merujuknya di kode Anda, serta di file (dan nama file) Anda / milik / Date.java. IDE lain mungkin memiliki fitur serupa.
MatrixFrog

16
Saya tidak setuju dengan pernyataan terakhir. Jika Anda ingin mendesain kelas Date Anda sendiri, Dateini adalah nama yang sempurna. Anda akan menggunakannya di sebagian besar kode Anda. Namun, terkadang Anda perlu menelepon java.util.Dateterutama untuk membuat konversi di antara keduanya.
paradigmatik

2
@MatrixFrog Fitur di Eclipse yang telah Anda tentukan juga disediakan oleh Netbeans IDE. Fitur ini dikenal sebagai "Refactor". Info Anda tidak salah tetapi itu bukan jawaban dari pertanyaan yang diajukan. Jika dia (Roger) mengembangkan kode itu, maka pasti dia tahu bahwa dia dapat mengubah atau mengubah nama Kelasnya. Apa yang dia tanyakan berbeda dengan jawaban yang Anda berikan.
Yatendra Goel

11
@Yatendra Itulah mengapa saya menambahkannya sebagai komentar daripada jawaban. Saya memperluas poin yang dibuat Ellie P. di akhir jawabannya. Roger mungkin tahu itu, tapi inti dari SO adalah membantu pengembang lain, bukan hanya orang yang mengajukan pertanyaan itu. Jika orang-orang tidak mengetahui tentang fitur IDE, mereka mungkin berpikir bahwa tidak mungkin untuk mengganti nama secara manual, jadi saya pikir akan berguna untuk memasukkan info itu.
MatrixFrog

5
Bentrokan nama saya yang paling sering terjadi dengan org.apache.log4j.Loggerdan java.util.logging.Logger. Biasanya, saya tidak memiliki kendali atas satu sisi atau sisi lainnya; Saya melakukan integrasi kode lama.
kevinarpe

21

gunakan nama yang sepenuhnya memenuhi syarat alih-alih mengimpor kelas.

misalnya

//import java.util.Date; //delete this
//import my.own.Date;

class Test{

   public static void main(String [] args){

      // I want to choose my.own.Date here. How?
      my.own.Date myDate = new my.own.Date();

      // I want to choose util.Date here. How ?
      java.util.Date javaDate = new java.util.Date();
   }
}

6
Praktik terbaik adalah mengimpor yang paling sering digunakan, menggunakan yang paling
jarang

10

Ya, saat Anda mengimpor kelas dengan nama sederhana yang sama, Anda harus merujuknya dengan nama kelas yang sepenuhnya memenuhi syarat. Saya akan membiarkan pernyataan import di, karena ini memberi pengembang lain gambaran tentang apa yang ada di dalam file saat mereka mengerjakannya.

java.util.Data date1 = new java.util.Date();
my.own.Date date2 = new my.own.Date();

7

Cara lain untuk melakukannya adalah subclass it:

package my.own;

public class FQNDate extends Date {

}

Dan kemudian impor my.own.FQNDate dalam paket yang memiliki java.util.Date.


Saya suka ini kecuali (sederhana) namun tidak mengatasi masalah untuk mengatakan mengakses metode statis.
Justin Ohms

Saya melakukan ini sepanjang waktu ketika saya ingin menggunakan Hamcrest Matchersdan Mockito Matchersdi kelas yang sama. Tampaknya berfungsi dengan metode statis.
Adam Burley

@Kidburla Anda juga dapat menggunakan impor statis selama Anda tidak peduli dari mana matcher berasal. Saya sering melakukan ini dalam pengujian unit untuk matcher dan .whens, .thenReturns , dll. - menghilangkan Mockito.mengasapi.
CptBartender

Ini adalah praktik yang buruk. Kelas tidak boleh diperpanjang kecuali beberapa fungsionalitas diperluas dari kelas aslinya.
Partha

3

Jika Anda memiliki kelas tanggal Anda sendiri, Anda harus membedakannya dari kelas Tanggal bawaan. yaitu mengapa Anda membuat sendiri. Sesuatu seperti ImmutableDate atau BetterDate atau NanoDate, bahkan MyDate akan menunjukkan mengapa Anda memiliki kelas kencan Anda sendiri. Dalam hal ini, mereka akan memiliki nama yang unik.


3

Anda dapat mengimpor salah satunya menggunakan impor. Untuk semua kelas serupa lainnya, Anda perlu menentukan nama kelas yang memenuhi syarat. Jika tidak, Anda akan mendapatkan kesalahan kompilasi.

Misalnya:

import java.util.Date;

class Test{

  public static void main(String [] args){

    // your own date
    my.own.Date myOwndate ;

    // util.Date
    Date utilDate;
  }
}

2

Skenario ini tidak begitu umum dalam pemrograman dunia nyata, tetapi tidak terlalu aneh juga. Kadang-kadang terjadi bahwa dua kelas dalam paket yang berbeda memiliki nama yang sama dan kita membutuhkan keduanya.

Tidak wajib jika dua kelas memiliki nama yang sama, keduanya akan berisi fungsionalitas yang sama dan kita harus memilih salah satunya.

Jika kita membutuhkan keduanya, maka tidak ada salahnya menggunakan itu. Dan itu juga bukan ide pemrograman yang buruk.

Tetapi kita harus menggunakan nama kelas yang sepenuhnya memenuhi syarat (yang memiliki nama yang sama) untuk memperjelas kelas mana yang kita rujuk juga.

:)


2

Saya mengalami masalah ini ketika, misalnya, memetakan satu kelas ke kelas lain (seperti saat beralih ke satu set kelas baru untuk mewakili data orang). Pada titik itu, Anda memerlukan kedua kelas karena itulah inti kode - untuk memetakan satu sama lain. Dan Anda tidak dapat mengganti nama kelas di kedua tempat (sekali lagi, tugasnya adalah memetakan, bukan mengubah apa yang dilakukan orang lain).

Berkualifikasi penuh adalah salah satu cara. Tampaknya Anda tidak dapat benar-benar menyertakan kedua pernyataan impor, karena Java khawatir tentang "Orang" yang mana, misalnya.


2

Jika Anda benar-benar ingin atau perlu menggunakan nama kelas yang sama dari dua paket berbeda, Anda memiliki dua opsi:

1-pilih satu untuk digunakan dalam impor dan gunakan nama kelas yang sepenuhnya memenuhi syarat lainnya:

import my.own.Date;

class Test{

     public static void main(String[] args){

        // I want to choose my.own.Date here. How?
        //Answer:
        Date ownDate = new Date();

        // I want to choose util.Date here. How ?
        //Answer:
        java.util.Date utilDate = new java.util.Date();

     }
}


2-selalu gunakan nama kelas yang memenuhi syarat:

//no Date import
class Test{

  public static void main(String[] args){

    // I want to choose my.own.Date here. How?
    //Answer:
     my.own.Date ownDate = new my.own.Date();
    // I want to choose util.Date here. How ?
    //Answer:
     java.util.Date utilDate = new java.util.Date();

  }
}

0

Saya hanya mengalami masalah yang sama, apa yang saya lakukan, saya mengatur urutan library secara berurutan, misalnya ada java.lang.NullPointerException dan javacard.lang.NullPointerException. Saya membuat yang pertama sebagai pustaka default dan jika Anda perlu menggunakan yang lain, Anda dapat secara eksplisit menentukan nama kelas yang memenuhi syarat.


0

Saat Anda memanggil kelas dengan nama yang sama, Anda harus secara eksplisit menentukan paket dari mana kelas tersebut dipanggil.

Anda bisa melakukan seperti ini:

import first.Foo;

public class Main {
    public static void main(String[] args) {
        System.out.println(new Foo());
        System.out.println(new second.Foo());
    }
}



package first;

public class Foo {
    public Foo() {
    }

    @Override
    public String toString() {
        return "Foo{first class}";
    }
}



package second;

public class Foo {
    public Foo() {
    }

    @Override
    public String toString() {
        return "Foo{second class}";
    }
}

Keluaran:

Foo{first class}
Foo{second class}

Harap sertakan kode dari tangkapan layar di jawaban Anda.
Thomas Landauer
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.