java - 当我只有名称而没有包时,如何找到 Java 类?
问题描述
当我只有名称但没有包时,如何在 Java 中定位(并实例化)一个类?编码
Class<?> clazz = Class.forName( "className" );
抛出ClassNotFoundException尽管“className”在类路径上。它仅适用于完整的包名称。编码
URL url = SomeClass.getClass().getClassLoader().findResource( "className.class" );
返回空值。
这不是重复的,因为使用包列表的解决方案没有回答“没有包”的问题。相反,它们依赖于预定义或外部配置的包列表。因此,“仅通过简单名称来反射地查找类”并不是重复的,而是提供了一个涉及包的解决方案。
有没有可用的 Java 方法来实现这一点?
我自己的答案是:
不,Class、ClassLoader 或任何其他 Java 类都不提供此功能。我写了一个小班来解决这个问题。System.out.println的最后一行给出了类的位置。请随意使用并根据您的要求进行调整。
package com.lemcke.util;
import java.io.File;
import java.io.IOException;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
public class ClassLocator {
/**
* Locates a class by its name. Searches the whole {@code classpath}.
*
* @param name
* Name of the class (without package)
* @return full package name of the class or {@code null} if not found
*/
public String locateClass( String name ) throws IOException {
if ( name == null || name.length() == 0 ) {
return null;
}
if ( name.endsWith( ".class" ) == false ) {
name += ".class";
}
String found = null;
String cp = System.getProperty( "java.class.path" );
String[] paths = cp.split( "[,;]" );
for ( String pathname : paths ) {
System.out.println( pathname );
if ( pathname.endsWith( ".jar" ) ) {
found = locateClassInJar( name, pathname );
if ( found != null ) {
break;
}
} else {
found = locateClassInFolder( name, new File( pathname ) );
if ( found != null ) {
found = found.substring( pathname.length() + 1 );
break;
}
}
}
if ( found != null ) {
found = found.substring( 0, found.length() - ".class".length() )
.replace( '/', '.' ).replace( '\\', '.' );
}
return found;
}
private String locateClassInFolder( String name, File path )
throws IOException {
File f = new File( path + "/" + name );
if ( f.exists() ) {
return f.getPath();
}
String found = null;
for ( File entry : path.listFiles() ) {
if ( entry.isDirectory() ) {
System.out.println( entry );
found = locateClassInFolder( name, entry );
if ( found != null ) {
break;
}
}
}
return found;
}
private String locateClassInJar( String name, String jarpath )
throws IOException {
name = "/" + name;
JarFile jarFile = new JarFile( jarpath );
Enumeration<JarEntry> entries = jarFile.entries();
String found = null, entry = null;
while ( entries.hasMoreElements() ) {
entry = entries.nextElement().getName();
if ( entry.endsWith( name ) ) {
found = entry;
break;
}
}
jarFile.close();
return found;
}
/**
* @param args
* @throws IOException
*/
public static void main( String[] args ) throws IOException {
ClassLocator locator = new ClassLocator();
String found = locator.locateClass( args[0] );
System.out.println( "found = " + found );
}
}
解决方案
在一般情况下,无法通过部分名称加载类。
在实践中这是可能的,但并不容易。您可以查看 spring 源代码以检查它们是如何实现这一点的。
推荐阅读
- string - 优化分析文字游戏的程序
- mysql - MySQL - 哪个文件正在运行查询
- flutter - 如何处理 Flutter 应用程序中的垃圾邮件按钮点击?
- ios - Nativescript 提交到 Apple Store 失败并出现错误 ITMS-90034
- docker - 找不到 docker 的钥匙串访问权限
- objective-c - 无法解释此试飞崩溃报告
- c# - 从私钥创建以太坊公共地址
- java - 我正在尝试实施 Eratosthenes 筛,但它仅适用于小于 33 的数字
- c# - 在 VS Code 中调试 Powershell cmdlet(用 c# 编写)
- amazon-cloudformation - Cloudformation:如何将属性附加到预定义的存储桶?