java中的类自示例化

x7yiwoj4  于 2021-06-30  发布在  Java
关注(0)|答案(7)|浏览(394)

如何自示例化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
    }
}

我只想更改类名和name变量,而不必每次使用template类时都更改示例化类的方式。使用当前设置,我必须编辑行: Foo foo = new Foo(); 也许下面的线。
你可能还想知道我为什么要打电话 launch() 而不是在主方法内做所有事情。这是我从java老师那里学到的东西。这也是因为我不能在 main() 方法。

f45qwnt8

f45qwnt81#

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

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

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

$> java mypackage.Foo

我不知道你为什么选择实施 Bar 接口;从你的问题来看,这似乎没有必要。

ymzxtsji

ymzxtsji2#

如果不打算对引用调用多个方法,为什么要存储引用?

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

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

2izufjch

2izufjch3#

如果你“实现”了什么,你需要定义一个接口。要么导入一个已经存在的,要么必须创建它。无论哪种方式,如果它是公共类(抽象或非抽象)或接口,则必须在单独的文件中定义。与c++不同,这是一个java需求。
如果:

public class Foo implements Bar { 
}

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

Foo.java
Bar.java

句号。没有如果/和/但是。
但是,如果您的项目中必须只有一个文件,则必须获得字节码生成器,并在运行时动态构建类和接口。
真正的问题是:你想完成什么?如果是单件/工厂,其他人已经回答了这个问题。如果是为了减少编译单元的数量,那你就走运了。java强制要求您必须这样做。
作者更新后编辑:
java允许您这样做:
foo.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() { } 
}

....

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

8wtpewkr

8wtpewkr4#

这里没有人听说过java中的嵌套/内部类吗?它们从9年前新推出的jdk1.2开始就存在了。

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!");
        }
    }
}

您可以将类嵌套到基本上任意的深度,使用包含类作为模块,并包含嵌套类和接口的任意集合。包括 main(String[]) 您为您的程序提供了一个入口点,可以从中启动程序。
这种方法将为您提供一个源文件,从中可以生成任意数量的类文件。嵌套类都将具有唯一的名称(不同于在顶层包含多个非公共类的黑客行为)。

0md85ypi

0md85ypi5#

怎么样?

public class Foo {

    private void instantiate()  {
        Foo foo = Foo.class.newInstance();
    }
    //...
}
gj3fmq9x

gj3fmq9x6#

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

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");
    }
}

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

4szc88ey

4szc88ey7#

或者用main方法:

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;
    }
}

相关问题