反射类的三种方法:1、Class xxx = 类名.class,当表示类类型的时候Class需要大写2、使用getClass()方法、需要已知该类的对象
3、使用forName(类的全称)方法、在使用forName方法时需要包含在try{}catch(){}异常处理中进行使用
public class Phone {
//属性
String screen = "qwer";
int cpu;
//方法
public void method01(){
System.out.println("第一个公有方法");
}
private void method02(){
System.out.println("第二个私有方法");
}
public static void main(String[] args) {
//获取类类型(Class对象)
//第一个表达式
Class c1 = Phone.class;
//第二个表达方式,已知该类的对象
Phone phone = new Phone();
Class c2 = phone.getClass();
//第三个表达式
//Class c3 = null;
try {
Class<?> c3 = Class.forName("Phone");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
如果直接使用forName()方法,会报一个未处理的错误、需要添加到try/catch异常处理中public class Phone {
//属性
String screen = "qwer";
int cpu;
//方法
public void method01(){
System.out.println("第一个公有方法");
}
private void method02(){
System.out.println("第二个私有方法");
}
public static void main(String[] args) {
//第三个表达式
Class c3 = null;
c3 = Class.forName("Phone"); //在这里forName()会报错,需要写到异常处理方法内、参数为类的全称
}
}
在IDEA中我们可以选中forName()方法,然后使用Ctrl+Alt+T,选中try/catch添加一个异常处理方法,就可以正常使用了。实例化对象:newinstance()实例化对象,它生成的对象只能反射无参的构造函数Constructor.newinstance()可以反射所有构造函数,包括私有的
//实例化类的对象
//第一个表达式
try {
Phone.class.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
//第二个表达式
try {
Class.forName("Phone").newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//第三个表达式
try {
Phone.class.getConstructor().newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
方法:Method类,方法的对象,一个成员方法就是一个Method对象getMethods()方法获取的是所有的public,包括父类继承的,不能获取私有方法getDeclaredMethods()获取的是所有该类自己声明的方法,无视访问权限invoke执行方法如果这个方法是普通方法,那么第一个参数时类对象如果这个方法是静态方法,那么第一个参数时类
//调用方法
try {
//获取方法
Method m1 = c2.getDeclaredMethod("method02");
//执行方法
try {
m1.invoke(c2.newInstance());
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
try {
Method m2 = c2.getMethod("method01");
try {
m2.invoke(c2.newInstance());
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
属性(成员变量):getFields()方法获取的是所有的Public的成员变量的信息getDeclaredFields()获取的是该类所有声明的成员变量信息//获取类的属性(成员变量)的信息
//getFields()方法获取的是所有的Public的成员变量的信息
Field[] fs01 = c1.getFields();
for (Field field : fs01){
//成员变量的类型的类类型
Class fieldType = field.getType();
String typeName = fieldType.getName();
//成员变量的名称
String fieldName = field.getName();
System.out.println(typeName+" "+fieldName);
}
//getDeclaredFields()获取的是该类所有声明的成员变量信息
Field[] fs02 = c1.getDeclaredFields();
for (Field field:fs02){
//得到成员变量的类型的类类型
Class fieldType = field.getType();
String typeName = fieldType.getName();
//得到成员变量的名称
String fieldName = field.getName();
System.out.println(typeName+" "+fieldName);
}
从结果可以看出,getFields()只能获取到类的公开的成员变量信息getDeclaredFields()可以获取该类所有声明的成员变量信息实例:通过反射调用java.lang.runtime类,并执行系统命令。一开始是这么写的,出现错误说是java.lang为私有属性、不可以访问。原因是Runtime类的构造器是私有修饰的,无法直接获取runtime类的实例,只能通过getRuntime()方法来间接获取一个Runtime类的实例运行一下,可以成功执行命令打开记事本但是当我们执行cmd命令时无法打开cmd窗口网上存在一些方法,可以解决这个问题。测试了一下发现只能执行dir命令,执行其他命令运行完成后cmd窗口会闪退,但是不影响程序的运行。我们可以直接使用echo函数写入一个文件当我们需要运行一个应用程序的时候,需要在写入这个程序的绝对路径如果该应用程序添加了环境变量或者在system32目录下,则不用写入绝对路径这样就可以直接打开远程桌面程序。