&引用;“你好,世界”;使用Java注释
问题描述:独立编译2个jar文件,而不必在类路径上包含彼此;在运行时,在一个jar中包含和调用main()以在标准输出上打印字符串。部分输出字符串必须来自第二个jar 约束:解决方案不能依赖于IDE或使用任何其他jar文件 回答到目前为止我做了什么:我的解决方案描述如下 问这个问题的原因:我试图弄清楚是否/如何使用注释来解决这个问题(希望以更优雅的方式),但找不到任何合适的文档或教程。我也很感激你的指点 我的解决方案:一个批处理文件(在Unix上,请将反斜杠改为正斜杠,分号改为冒号,rem改为#),如下所示:&引用;“你好,世界”;使用Java注释,java,annotations,Java,Annotations,问题描述:独立编译2个jar文件,而不必在类路径上包含彼此;在运行时,在一个jar中包含和调用main()以在标准输出上打印字符串。部分输出字符串必须来自第二个jar 约束:解决方案不能依赖于IDE或使用任何其他jar文件 回答到目前为止我做了什么:我的解决方案描述如下 问这个问题的原因:我试图弄清楚是否/如何使用注释来解决这个问题(希望以更优雅的方式),但找不到任何合适的文档或教程。我也很感激你的指点 我的解决方案:一个批处理文件(在Unix上,请将反斜杠改为正斜杠,分号改为冒号,rem改为#
rem Compile and package the testing class (Main) without any library
javac -d target core\*.java
cd target
jar cvf ..\main.jar .\core
cd ..
rem Compile and package the Greeting and Greeted classes as a library
javac -d lib impl\*.java
cd lib
jar cvf ..\mylib.jar .\impl
cd ..
rem Use the two parts above at runtime and execute main() in Main class
java -cp main.jar;mylib.jar core.Main
impl目录中有2个文件,core中有2个文件,如下所示:
rem Compile and package the testing class (Main) without any library
javac -d target core\*.java
cd target
jar cvf ..\main.jar .\core
cd ..
rem Compile and package the Greeting and Greeted classes as a library
javac -d lib impl\*.java
cd lib
jar cvf ..\mylib.jar .\impl
cd ..
rem Use the two parts above at runtime and execute main() in Main class
java -cp main.jar;mylib.jar core.Main
/*文件:impl/Greeting.java*/
package impl;
public class Greeting {
public String getGreeting () {
return "Hello";
}}
/*文件:impl/helleed.java*/
package impl;
public class Greeted {
public String getGreeted () {
return "world";
}
/*文件:core/Main.java*/
package core;
public class Main {
private String greeting = "Learn annotations", greeted = "keep using Java",
// Can read the following 4 values from a configuration file, too
// Trying to see if we can get these using Java annotations
greetingClassName = "impl.Greeting", greetingMethod = "getGreeting",
greetedClassName = "impl.Greeted", greetedMethod = "getGreeted";
public Main () {
try {
MyRunTime runTime = new MyRunTime();
Object gting = runTime.getInstance(greetingClassName),
gted = runTime.getInstance(greetedClassName),
g1Str = runTime.getResponseNoArg (gting, greetingMethod),
g2Str = runTime.getResponseNoArg (gted, greetedMethod);
if (g1Str instanceof String) greeting = (String) g1Str;
if (g2Str instanceof String) greeted = (String) g2Str;
} catch (Exception ex) {
System.err.println ("Error in Library loading: " + ex.getMessage());
}}
public void greet () {
System.out.println (greeting + ", " + greeted + "!");
}
public static void main (String[] args) {
new Main().greet();
}}
/*文件:core/MyRunTime.java*/
package core;
import java.lang.reflect.*;
public class MyRunTime {
public Object getResponseNoArg (Object anInstance, String methodName) throws
NoSuchMethodException,
IllegalAccessException,
InvocationTargetException {
Method method = anInstance.getClass().getMethod (methodName);
return method.invoke (anInstance);
}
public Object getInstance (String className) throws
ClassNotFoundException,
InstantiationException,
IllegalAccessException {
Class c = Class.forName (className);
return c.newInstance();
}
}
就这样。除非绝对必要,否则我也不想搞乱类加载器。一旦我掌握了如何使用注释实现这一点,我就可以研究传递参数并继续。谢谢您的帮助。我不会为此使用注释-可能值得介绍什么是注释以及它们在哪里使用得最好 相反,我会这样做:
public class Main {
public static void main(final String[] args) throws java.lang.Throwable {
final String list = System.getProperty( "java.class.path" );
for (String path : list.split( ";" )) {
java.io.File object = new java.io.File( path );
if ( object.isDirectory() )
for ( String entry : object.list() ) {
java.io.File thing = new java.io.File( entry );
if ( thing.isFile() )
System.out.println( thing );
else if( object.isFile() )
System.out.println( object );
}
}
}
}
- 在每个jar中放置不同的文件
- 每个jar文件都有一个主类,其作用相同:列出类路径上的文件
public class Main {
public static void main(final String[] args) throws java.lang.Throwable {
final String list = System.getProperty( "java.class.path" );
for (String path : list.split( ";" )) {
java.io.File object = new java.io.File( path );
if ( object.isDirectory() )
for ( String entry : object.list() ) {
java.io.File thing = new java.io.File( entry );
if ( thing.isFile() )
System.out.println( thing );
else if( object.isFile() )
System.out.println( object );
}
}
}
}
你会说,“我正在试图弄清楚是否/如何使用注释来解决这个问题。”为什么?注释中有什么让您希望使用它们来解决所描述的问题?这是家庭作业吗?有没有其他你没有给我们的指示?为什么?好奇的人想知道。有什么。。。?不知何故,我使用过的大多数框架都使用注释进行依赖注入/IoC/不管你怎么称呼它。这些框架的创造者无疑是聪明人,我正试图理解他们的逻辑。不,这不是家庭作业。附加说明:我不确定你的意思,但我所描述的几乎是一个完整的描述。从你的评论来看,我是否应该假设答案是“注释与所描述的问题无关”?是的,这是我的观点。我认为注释不会在解决问题描述的过程中增加太多内容。我看到的大多数注释用法都涉及确定类的其他行为,而不是如何定位它。在编译包含Main.Main(String[])方法的“a.jar”时,我们不知道“b.jar”的存在,甚至不知道它包含的类。主类不知道它需要的对象或要调用的方法(在我的示例中,变量xxClassName和xxMethod将在运行时从配置文件中读入)。您的建议是扫描类路径上的每个jar文件,并检查命名对象(类)是否在其中一个文件中。我已经可以用Class.forName()完成这项工作,并使用反射来检查该方法。这就是我现在正在做的。我正在寻找的是如何在注释(例如greetingClassName)中读取一个值(例如Greeting),然后在运行时找到一个注释为“@Greeting”的类。这样,我就可以有几个问候类的实现(在不同的jar文件甚至包中),并选择一个具有正确注释的实现。这是一种使用注释的好方法,还是我完全偏离了标准?如果在jar a中定义注释,您将在使用它的所有jar中创建编译和运行时依赖关系-这违反了规范。这就是我试图解决的问题。我想从配置文件(比如greetable)中读取接口的名称,并在运行时找到实现greetable的类,创建其实例等等。(1) 我在哪里定义接口(可能在“b.jar”中,因为实现也在“b.jar”中)。你认为这样可以消除编译依赖吗?