10
回答
反射带有自定义类型参数的方法时出现NoSuchMethodException
注册华为云得mate10,2.9折抢先购!>>>   
public class Test {
// 需要反射的方法
	public Iphone5S test4(Iphone5S iphone){
		

		System.out.println("test4 运行了!!!!");
		return iphone;
	}

}
public class Iphone5S {
	private int price;
	private String volume ;
	
	public int getPrice() {
		return price;
	}
	public void setPrice(int price) {
		this.price = price;
	}
	public String getVolume() {
		return volume;
	}
	public void setVolume(String volume) {
		this.volume = volume;
	}
	
}




public static void main(String[] args) throws Exception {
	
		
		Class iphone5sClass = ClassUtils.getClass("test.Iphone5S");
		
		Object iphone5s = iphone5sClass.newInstance();
		ClassUtils.setPropertyValue(iphone5s, "price", 5899);
		ClassUtils.setPropertyValue(iphone5s, "volume", "16g");
		
		
		Class clazz = ClassUtils.getClass("test.Test");
		Method test4 = clazz.getMethod("test4", iphone5sClass);

		
		test4.invoke(clazz.newInstance(), iphone5s);


	}


异常信息:

Exception in thread "main" java.lang.NoSuchMethodException: test.Test.test4(test.Iphone5S)
    at java.lang.Class.getMethod(Class.java:1605)
    at Test.demo.Main.main(Main.java:33)

我自己调试了一下 发现问题应该出在被调用方法的参数上 我将方法参数列表去掉后 方法正常调用 难道是用反射时不能调用带有自定义类型的方法吗? test类 与 iphone5s类被打包到一个jar中 请大牛帮我解答 谢谢 感激不尽啊

举报
刀剑千秋
发帖于4年前 10回/3K+阅
共有10个答案 最后回答: 4年前

Test.class.getMethod() 

遍历这个数组,看看能遍历出什么方法签名

--- 共有 1 条评论 ---
刀剑千秋打印出来了 public test.Iphone5S test.Test.test4(test.Iphone5S) 但是还是报错 怎么办啊 ? 4年前 回复

public static void main(String[] args) throws Exception {

Iphone5S ip = new Iphone5S();
Class<?> iphone5sClass = ip.getClass();

Object iphone5s = iphone5sClass.newInstance();
//ClassUtils.setPropertyValue(iphone5s, "price", 5899);
//ClassUtils.setPropertyValue(iphone5s, "volume", "16g");
Field field1 = iphone5sClass.getDeclaredField("price");
Method method1= iphone5sClass.getDeclaredMethod("setPrice", field1.getType());

Field field2 = iphone5sClass.getDeclaredField("volume");
Method method2 = iphone5sClass.getDeclaredMethod("setVolume", field2.getType());

method1.invoke(iphone5s, 5899);
method2.invoke(iphone5s, "16g");

Test test = new Test();
Class<?> clazz = test.getClass();
Method test4 = clazz.getMethod("test4", iphone5sClass);
test4.invoke(clazz.newInstance(), iphone5s);
}

这样就可以运行了。。。。 ClassUtils是啥包的?

--- 共有 1 条评论 ---
刀剑千秋还是不好使啊 我的 test类 和 iphone5s类都打包成jar了 4年前 回复

引用来自“小菜的奥特曼”的评论

public static void main(String[] args) throws Exception {

Iphone5S ip = new Iphone5S();
Class<?> iphone5sClass = ip.getClass();

Object iphone5s = iphone5sClass.newInstance();
//ClassUtils.setPropertyValue(iphone5s, "price", 5899);
//ClassUtils.setPropertyValue(iphone5s, "volume", "16g");
Field field1 = iphone5sClass.getDeclaredField("price");
Method method1= iphone5sClass.getDeclaredMethod("setPrice", field1.getType());

Field field2 = iphone5sClass.getDeclaredField("volume");
Method method2 = iphone5sClass.getDeclaredMethod("setVolume", field2.getType());

method1.invoke(iphone5s, 5899);
method2.invoke(iphone5s, "16g");

Test test = new Test();
Class<?> clazz = test.getClass();
Method test4 = clazz.getMethod("test4", iphone5sClass);
test4.invoke(clazz.newInstance(), iphone5s);
}

这样就可以运行了。。。。 ClassUtils是啥包的?


ClassUtils是自己写的反射工具类 粘贴部分内容
public class ClassUtils {

	/**
	 * "set"
	 */
	public static final String SET = "set";

	/**
	 * "get"
	 */
	public static final String GET = "get";

	// ------------------------------------------------//

	/**
	 * 判断对象是否为空
	 * 
	 * @param object
	 *            对象
	 * @return 为空-true 否则-false
	 */
	public static boolean isNull(Object object) {

		return object == null ? true : false;
	}

	/**
	 * 对象为空时抛出运行时异常
	 * 
	 * @param object
	 *            对象
	 * @param message
	 *            异常消息
	 */
	public static void isNullToRuntimeException(Object object, String message) {

		if (isNull(object))
			throw new RuntimeException(message);
	}

	// ------------------------------------------------//

	/**
	 * 根据类全名称获取该类Class对象
	 * 首先使用系统默认加载器加载,如果没有找到,则使用自定义加载器加载目录外部jar
	 * @param className 类全名称
	 * @param url 外部目录
	 * @param isFile 是否为文件
	 * @return Class对象
	 */
	public static Class getClass(String className, String url, boolean isFile){
		Class clazz = null;

		try {
			clazz = Class.forName(className);
		} catch (Exception e) {
			try {
				clazz = ClassLoad.getURLClassLoader(url, isFile).loadClass(className);
			} catch (ClassNotFoundException e1) {
				throw new RuntimeException(e1);
			}
		}
		return clazz;
	}
	
	/**
	 * 根据类全名称获取该类Class对象
	 * 首先使用系统默认加载器加载,如果没有找到,则使用自定义加载器加载目录外部jar
	 * 默认为文件夹
	 * @param className 类全名称
	 * @param url 外部目录
	 * @return Class对象
	 */
	public static Class getClass(String className, String url){
		Class clazz = null;

		try {
			clazz = Class.forName(className);
		} catch (Exception e) {
			try {
				clazz = ClassLoad.getURLClassLoader(url).loadClass(className);
			} catch (ClassNotFoundException e1) {
				throw new RuntimeException(e1);
			}
		}
		return clazz;
	}
	
	/**
	 * 根据类全名称获取该类Class对象
	 * 首先使用系统默认加载器加载,如果没有找到,则使用自定义加载器加载默认目录外部jar,目录在config.xml中配置,key : defaultLoadClassPath
	 * @param className 类全名称
	 * @param isFile 是否是文件
	 * @return Class对象
	 */
	public static Class getClass(String className, boolean isFile){
		Class clazz = null;

		try {
			clazz = Class.forName(className);
		} catch (Exception e) {
			try {
				clazz = ClassLoad.getURLClassLoader(isFile).loadClass(className);
			} catch (ClassNotFoundException e1) {
				throw new RuntimeException(e1);
			}
		}
		return clazz;
	}
	
	/**
	 * 根据类全名称获取该类Class对象
	 * 首先使用系统默认加载器加载,如果没有找到,则使用自定义加载器加载默认目录外部jar,目录在config.xml中配置,key : defaultLoadClassPath
	 * 默认目录为文件夹
	 * @param className 类全名称:包.类名
	 * @return 该类Class对象
	 */
	public static Class getClass(String className) {

		Class clazz = null;

		try {
			clazz = Class.forName(className);
		} catch (Exception e) {
			try {
				clazz = ClassLoad.getURLClassLoader().loadClass(className);
			} catch (ClassNotFoundException e1) {
				throw new RuntimeException(e1);
			}
		}
		return clazz;
	}

	
}

引用来自“superxinlee”的评论

是有点奇怪啊,把3个class文件发过来看看。

奇怪 是因为我把需要反射的class文件 打包成jar 了 怎么在提问里上传文件?

打成jar包,要load的

以/结尾只会load该目录下的class

urlClassLoader

该类加载器用于从指向 JAR 文件和目录的 URL 的搜索路径加载类和资源。这里假定任何以 '/' 结束的 URL 都是指向目录的。如果不是以该字符结束,则认为该 URL 指向一个将根据需要打开的 JAR 文件。

创建 URLClassLoader 实例的 AccessControlContext 线程将在后续加载类和资源时使用。

为加载的类默认授予只能访问 URLClassLoader 创建时指定的 URL 的权限。 

顶部