package yerasel;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
public class Test {
public static void main(String[] args) {
// ClassLoader
Class c1;
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
try {
// 加载student类
String className = "yerasel.Student";
//c1 = classLoader.loadClass("yerasel.Student");
c1 = Class.forName(className);
/*
* Class.forName("xx.xx")等同于Class.forName("xx.xx",true,CALLClass.class.getClassLoader()),
* 第二个参数(boolean)表示装载类的时候是否初始化该类,即调用类的静态块的语句及初始化静态成员变量。
* ClassLoader loader = Thread.currentThread.getContextClassLoader();
* 也可以用(ClassLoader.getSystemClassLoader())
*/
System.out.println(c1);
// 获得加载类的所有方法
Field[] fields = c1.getFields();
// 遍历输出
for (int i = 0; i < fields.length; i++) {
System.out.println(fields[i].getName());
System.out.println(fields[i].getType());
System.out.println(fields[i].getModifiers());
}
Field stuName = c1.getField("name");
// 获得c1中的方法
Class[] parameterTypes = {};
Method method = c1.getMethod("say", parameterTypes);
// 实例化c1对象
Object obj = c1.newInstance();
// 通过实例化后的对象调用c1中方法
method.invoke(obj, null);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 动态加载jar
try {
// 包路径定义
URL urls = new URL("file:/C:/Users/Yerasel/workspace/ReflectTest/bin/yerasel/GetPI.jar");
//GetPI.class
URLClassLoader urlLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
Class<URLClassLoader> sysclass = URLClassLoader.class;
Method method = sysclass.getDeclaredMethod("addURL", new Class[]{URL.class});
method.setAccessible(true);
method.invoke(urlLoader, urls);
/*
* 实例化一个对象 ,这个类(yerasel.GetPI)可以是串行化传来的多个类的一个,运行时才知道需要哪个类
* 或者从xml 配置文件中获得字符串
* 例如
* String className = readfromXMlConfig;//从xml 配置文件中获得字符串
* class c = Class.forName(className);
* factory = (ExampleInterface)c.newInstance();
* 上面代码已经不存在类名称,它的优点是,无论Example类怎么变化,上述代码不变,
* 甚至可以更换Example的兄弟类Example2 , Example3 , Example4……,只要他们继承ExampleInterface就可以。
*/
// 输入类名
String className = "yerasel.GetPI";
Class<?> tidyClass = urlLoader.loadClass(className);
Object obj = tidyClass.newInstance();
// 被调用函数的参数
Class[] parameterTypes = {};
Method method2 = tidyClass.getDeclaredMethod("Output", parameterTypes);
method2.invoke(obj, null);
} catch (Exception exp) {
exp.printStackTrace();
}
}
}
class Student {
public String name;
public int age;
protected String nicai;
private int hh;
public void say() {
System.out.println("I‘m student");
}
}
生成jar包的命令
jar cvf GetPI.jar GetPI.class
jar放入ReflectTest工程的yerasel/bin中。
GetPI.java内容为
package yerasel;
import java.math.*;
public class GetPI {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(Darts(100000));
}
public static double Darts(int n)
{
int k = 0;
double x = 0;
double y = 0;
for (int i = 0; i < n; i++)
{
x = Math.random();
y = Math.random();
if ( (x * x + y * y) <= 1)
k++;
}
return (4 * k / (double)n);
}
public static void Output()
{
System.out.println("Output");
}
}
文件结构如下: