代码之家  ›  专栏  ›  技术社区  ›  Ramon Marco L. Navarro

Java中的自实例化

  •  1
  • Ramon Marco L. Navarro  · 技术社区  · 16 年前

    我如何实例化Java类?除了类文件之外,我不应该使用任何文件。另外,假设在我初始化name变量的行之后,它们在编译期间不知道类的名称。

    例子:

    public class Foo implements Bar {
        public static final String NAME = "Foo";
    
        private void instantiate()  {
            Bar baz = (Bar)Class.forName(NAME).newInstance();
        }
        //...
    }
    

    可能是错误的,因为它需要另一个名为 Bar.java . 应该是:

    public class Foo {
        /*
        Instantiate self...
        */
    }
    

    我加入了这个编程挑战网站,每个问题只允许提交一个文件。我想为我将用于挑战的所有类创建一个模板类。所以,我想我会这样做:

    public class Foo {
        public static final String NAME = "Foo";
    
    
        public static void main (String[] args) throws IOException {
            //Instantiate self and call launch(args)
            Foo foo = new Foo();
            foo.launch(args);
            System.exit(0);
        }
    
        public void launch(String[] args) {
            //...Do actual code here
        }
    }
    

    我只想更改类名和名称变量,而不必在每次使用模板类时更改类的实例化方式。使用当前设置,我必须编辑行: Foo foo = new Foo(); 可能是下面的那条线。

    你也可能想知道我为什么要打电话 launch() 不要在主要方法中做任何事情。这就是我从Java老师那里学到的东西。因为我不能在 main() 方法。

    7 回复  |  直到 16 年前
        1
  •  1
  •   Chris K    16 年前

    如果你“执行”任何事情,你 需要 定义接口。要么导入一个已经存在的,要么必须创建它。不管是哪种方式,如果它是公共类(抽象的还是非抽象的)或接口,那么 必须 在单独的文件中定义。与C++不同,这是Java的要求。

    如果:

    public class Foo implements Bar { 
    } 
    

    那么您的项目必须至少包括:

    Foo.java
    Bar.java 
    

    时期。没有条件。

    但是,如果项目中必须只有一个文件,那么您必须获得一个字节代码生成器,并在运行时动态地构建类和接口。

    真正的问题是:你想完成什么?如果是单件/工厂,其他人已经回答过了。如果要减少编译单元的数量,那你就走运了。Java强制要求你必须这样做。

    作者更新后编辑:

    Java允许你这样做:

    爪哇 :

    public class Foo { 
      public static void main(String[] args) { 
        Bar bar = new Bar(); 
      }
    }
    class Bar { 
       int bar_var; 
       Snafu fu = new Snafu(); 
    
       public Bar() {  } 
       public int getBarVar() { return bar_var; } 
    } 
    class Snafu { 
       int var; 
       public Snafu() { } 
    }
    
    .... 
    

    这将实现你想要实现的目标。

        2
  •  1
  •   BalusC    16 年前

    您已编辑了邮件并添加了更多信息。那很好。现在问题更清楚了。你实际上在寻找工厂模式。

    public abstract class Batch {
        public static void main(String[] args) throws Exception {
            Batch batch = (Batch) Class.forName(args[0]).newInstance();
            batch.run();
        }
    
        abstract void run();
    }
    
    class Foo extends Batch {
        public void run() {
            System.out.println("Executing Foo");
        }
    }
    
    class Bar extends Batch {
        public void run() {
            System.out.println("Executing Bar");
        }
    }
    

    第一个参数显然是类名。希望这有帮助。

        3
  •  1
  •   Richard Copperwaite    16 年前

    如果不调用一个以上的方法,为什么要存储一个引用?

    public class Foo {
      public static void main(String[] args){
        new Foo().launch(args);
      }
      public void launch(String[] args){
        //...
      }
    }
    

    在这里,为每个问题更改文件只需要更改两行:类头和 new 条款!容易的!

        4
  •  0
  •   oxbow_lakes    16 年前

    你需要一个 main 你的方法 Foo 调用其构造函数的类:

    public static void main(String[] args) {
        Foo f = new Foo(); //the new syntax uses a Constructor, not reflection
        //etc
    

    然后你可以 运行 课程通过 java 可执行文件(将调用主方法):

    $> java mypackage.Foo
    

    我不知道你为什么选择执行 Bar 接口;从您的问题来看,这似乎是不必要的。

        5
  •  0
  •   NawaMan    16 年前

    怎么样?

    public class Foo {
    
        private void instantiate()  {
            Foo foo = Foo.class.newInstance();
        }
        //...
    }
    
        6
  •  0
  •   Rontologist    16 年前

    或者用主要方法:

    public class Foo implements Bar {
        public static final String NAME = "Foo";
    
        public static void main(String[] args) {
            Foo f = new Foo();
        }
    

    或作为初始值设定项:

    public class Foo implements Bar {
        public static final String NAME = "Foo";
        private static final instance = new Foo();
    
        private void getInstance()  {
            return instance;
        }
    }
    
        7
  •  0
  •   bendin    16 年前

    这里没有人听说过Java中的嵌套/内部类吗?它们从JDK1.2开始就存在了,这是9年前的新产品。

    public class Main {
        public static void main(String[] args) {
            Bar b = new Foo();
            b.doSomethingExciting();
        }
        interface Bar {
            void doSomethingExciting();
        }
        static class Foo implements Bar {
            public void doSomethingExciting() {
                System.out.println("Boo!");
            }
        }
    }
    

    可以使用包含类作为 Module 并包含嵌套类和接口的任意集合。通过包括 main(String[]) 您为程序提供了一个入口点,从中可以启动程序。

    这种方法会给你 一 可以从中生成任意数量类文件的源文件。嵌套类都将具有唯一的名称(与在顶层包含多个非公共类的方法不同)。

    推荐文章