java反射机制:
Java反射(Reflection)就是Java程序在运行时,可以加载、探知、使用编译期间完全未知的类。也就是说,Java程序可以加载一个运行时才得知类名的类,获得类的完整构造方法,并实例化出对象,给对象属性设定值或者调用对象的方法。这种在运行时动态获取类的信息以及动态调用对象的方法的功能称为Java的反射机制。
本次练习为通过反射获取方法、获取属性、获取构造方法、创建对象、修改属性、调用方法、动态创建一二维数组等。实例代码如下:
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.*;
import java.util.Properties;
import java.util.Scanner;
public class reflect {
public static void main(String[] args) throws Exception{
Drive drive = new Drive("晓");
String name ="cn.lanqiao.test.Drive";
//getClass(name);
SetTwoArrays(name);
//SetConstructor(name);
// try {
// SetClassAndMenthod(name);
// } catch (IOException e) {
// e.printStackTrace();
// }
//SetArrays(name);
}
//通过该来获取原对象的属性、方法、构造方法、原生对象等
public static void getClass(String name){
Class c=null;
try {
c= Class.forName(name);
System.out.println("答案为"+c);
} catch (Exception e) {
e.printStackTrace();
}
finally {
Method[] methods = c.getDeclaredMethods();
for(Method method:methods){
System.out.println("Drive的方法为"+method);
}
System.out.println("==========");
Field[] field = c.getFields();
for(Field field1:field){
System.out.println(field1);
}
System.out.println("==========");
Constructor[] constructors = c.getConstructors();
for(Constructor constructor:constructors){
System.out.println("构造函数"+constructor);
}
System.out.println("==========");
Class[] interfaces = c.getInterfaces();
for(Class inter:interfaces){
System.out.println("继承的接口有"+inter);
}
System.out.println("==========");
String name1 = c.getName();
System.out.println("类名为"+name1);
}
}
//通过该来设置原对象的属性、方法、构造方法、原生对象等
public static void SetMethods2(String name) throws Exception{
Class driver = Drive.class;
Drive driver1 = (Drive) driver.newInstance();
/*设置driver1对象的名字*/
Field name1 = driver.getDeclaredField("name");
name1.setAccessible(true);
name1.set(driver1, "哈哈哈");
System.out.println("新名字:::" + driver1.getName());
//driver1.setName("黄大龙");
/*设置driver1对象的方法值*/
Method name2 = driver.getDeclaredMethod("ceshi");
Method eatMethod = driver.getDeclaredMethod("eat", String.class,Double.class);
Class<?>[] typeParameters = eatMethod.getParameterTypes();
for(Class<?> typeVariable:typeParameters){
System.out.println("typeVariable-->"+typeVariable);
}
//setAccessible是当该方法为private时使其允许进行写操作;
name2.setAccessible(true);
name2.invoke(driver1, null);
driver1.ceshi();
}
//通过方法该来设置原对象的构造方法
public static void SetConstructor(String name){
Class driver =Drive.class;
Constructor[] constructors =null;
constructors = driver.getDeclaredConstructors();
for(Constructor constructor:constructors){
System.out.println(constructor);
}
try {
//获取公共的构造方法并创建对象
Constructor constructor = driver.getConstructor(String.class);
Drive instance = (Drive)constructor.newInstance("晓");
System.out.println("新对象"+instance);
System.out.println(instance.getSex());
System.out.println("------------");
//获取私有的构造方法并创建对象
Constructor constructor2 = driver.getDeclaredConstructor(String.class,String.class);
//System.out.println(constructor2);
constructor2.setAccessible(true);
Drive instance2 = (Drive)constructor2.newInstance("黄大龙","男");
System.out.println("新对象2"+instance2);
System.out.println(instance2.getSex());
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
//通过方法该来动态加载类名和方法
public static void SetClassAndMenthod(String name) throws IOException {
String newName="proproties.txt";
Class<?> aClass =null;
Properties proper = new Properties();
proper.load(new FileReader("src/cn/lanqiao/test/proproties.txt"));
String classname = proper.getProperty("classname");
String method = proper.getProperty("methodname");
// System.out.println("method->"+method);
// System.out.println("classname->"+classname);
try {
aClass = Class.forName(classname);
System.out.println(aClass);
Method method1 = aClass.getDeclaredMethod(method,String.class);
System.out.println("method1->"+method1);
method1.setAccessible(true);
method1.invoke(aClass,"sfs");
System.out.println(aClass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
//通过方法该来操作动态一维数组
public static void SetOneArrays(String name){
Scanner scanner = new Scanner(System.in);
System.out.println("请输入数组的类型");
String type=scanner.nextLine();
System.out.println("请输入数组的长度");
int len=scanner.nextInt();
Class<?> aClass =null;
try {
aClass = Class.forName(type);
System.out.println("name->"+aClass.getName());
System.out.println("class->"+aClass.getClass());
System.out.println("classname->"+aClass.getClass().getName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Object newArray = Array.newInstance(aClass, len);
Array.set(newArray,0,"one");
Array.set(newArray,1,"two");
System.out.println(Array.get(newArray,0));
System.out.println(Array.get(newArray,1));
}
//通过方法该来操作动态二维数组
public static void SetTwoArrays(String name){
Class<Integer> arr = Integer.TYPE;
//定义一个3*3的二维数组
int[] dim={3,3};
//创建一个二维数组对象
Object instance = Array.newInstance(arr, dim);
//得到一个第二行的一维数组
Object arr2 = Array.get(instance, 2);
//设置这个一维数组的[2,2]的值为70
Array.set(arr2,2,70);
//获取这个一维数组的[2,2]的值
System.out.println(Array.get(arr2,2));
}
}