【问题标题】:Difference between using fully qualified name and import in Java在 Java 中使用完全限定名称和导入之间的区别
【发布时间】:2015-10-06 09:09:08
【问题描述】:

在 Java 中使用“内联导入”(完全限定名称)和普通导入在性能、内存、编译时间等方面有什么区别吗?

chooser.setCurrentDirectory(new java.io.File("."));

import java.io.File;
...
   chooser.setCurrentDirectory(new File("."));

【问题讨论】:

  • 没有区别,只有第二种方案更具可读性。只有在存在类冲突时才应使用inline imports
  • 我建议您使用第二个以获得更好的可读性。当您测量性能不佳时,还要担心性能。

标签: java import inline


【解决方案1】:

您应该关注的主要内容是可读性。我发现第二个更易读。

在极少数情况下,我更喜欢第二种方法。让我们考虑以下场景:出于某种原因,我编写了一个类并将其命名为File。我输入了File file = new File(...),我的IDE 自动为我导入了java.io.File。但我不想要那种对象,我想要 my File 类。因此,与其导入正确的类,我更喜欢内联导入它,这样其他用户就不会对 Java 的 File 类感到困惑。

关于性能,它们完全一样,这是证明 -

这是为第一个 sn-p 生成的字节码:

public class java8.tests.General {
  public java8.tests.General();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: new           #2                  // class javax/swing/JFileChooser
       3: dup
       4: invokespecial #3                  // Method javax/swing/JFileChooser."<init>":()V
       7: astore_1
       8: aload_1
       9: new           #4                  // class java/io/File
      12: dup
      13: ldc           #5                  // String .
      15: invokespecial #6                  // Method java/io/File."<init>":(Ljava/lang/String;)V
      18: invokevirtual #7                  // Method javax/swing/JFileChooser.setCurrentDirectory:(Ljava/io/File;)V
      21: return
}

这是第二个的字节码:

public class java8.tests.General {
  public java8.tests.General();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: new           #2                  // class javax/swing/JFileChooser
       3: dup
       4: invokespecial #3                  // Method javax/swing/JFileChooser."<init>":()V
       7: astore_1
       8: aload_1
       9: new           #4                  // class java/io/File
      12: dup
      13: ldc           #5                  // String .
      15: invokespecial #6                  // Method java/io/File."<init>":(Ljava/lang/String;)V
      18: invokevirtual #7                  // Method javax/swing/JFileChooser.setCurrentDirectory:(Ljava/io/File;)V
      21: return
}

【讨论】:

    【解决方案2】:

    在性能、内存、编译时间方面,两者都不完全相同。它们之间的唯一区别是正常导入可以节省您的打字工作,并且它更具可读性。

    【讨论】:

      【解决方案3】:

      仅在以下情况下才有意义,

      如果你想使用一个在多个包中可用的类。 即日期类在 java.util 和 java.sql 中可用

      您可以在程序开始时导入上述类中的一个,并为另一个使用合格的语法。

      【讨论】:

        【解决方案4】:

        如果您在一个类中导入同名的类,您可以明确地告诉在哪里使用哪一个(完整的类名):

        import java.io.File;
        ...
        chooser.setCurrentDirectory(new File(".")); // java.io.File
        
        new org.yourpackage.File("sdfsdf");         // org.yourpackage.File
        

        【讨论】:

          【解决方案5】:

          不,它不会影响代码的性能。 导入语句使您的代码更具可读性,因为您没有编写所有包名称。 但有时,您会遇到 ClassNames 冲突,那么建议使用限定名称。

          【讨论】:

            【解决方案6】:

            在 java 中,类总是由最终字节码中的完全限定名引用。它在创建类对象(或访问类的静态成员)时第一次发生。

            也就是说,import 被编译器用来通过其非限定名称(MyClass 而不是mypackage.MyClass)访问类。

            因此,导入类或显式编写完全限定名称之间存在 0 差异 - 这只是可读性的问题,节省了一些输入并有助于防止具有相同名称的类之间发生冲突。

            【讨论】:

              猜你喜欢
              • 2012-08-08
              • 1970-01-01
              • 2012-10-12
              • 1970-01-01
              • 1970-01-01
              • 2012-01-14
              • 1970-01-01
              • 2013-06-21
              • 1970-01-01
              相关资源
              最近更新 更多