命令执行

通过java.io.IOException实现命令执行

1
2
3
4
5
6
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException{
Runtime.getRuntime().exec("calc");
}
}

通过java.lang.ProcessBuilder实现命令执行

1
2
3
4
5
6
7
8
9
import java.lang.ProcessBuilder;
import java.io.IOException;
public class Main {
public static void main(String[] args)throws IOException{
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command("cmd", "/c", "calc");
Process process = processBuilder.start();
}
}

Java反射

1
2
Java中存在一个Class类,该类保存了对象和类的所有信息,可通过Class类获取Java中的类信息。
Java的反射就是将某个Java类中的方法或者变量等信息,映射成一个Java对象,通过映射后可获取其中的信息或执行其中的方法。

创建Class对象

通过以下几种方式创建Class对象后,可对其执行反射

作用 代码
获取类名称,并返回Class对象 Class.forName(“类名”)
根据现有对象,创建新的Class对象 对象名.getClass()
根据类名,创建Class对象 类名.class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.lang.Class;
import java.lang.reflect.*;

class Data {
int num = 99;
public void print() {
System.out.println("成功调用print方法");
}
}

public class Main {
public static void main(String[] args) throws ClassNotFoundException {
//方式一
Class data1 = Class.forName("Data");
//方式二
Data data = new Data();
Class data2 = data.getClass();
//方式三
Class data3 = Data.class;
}
}

反射调用方法(过渡)

通过下面的两个方法获取类中的方法,反射调用

作用 代码
返回类的方法 Class对象名.getMethods(“方法名”,”传参类型”)
反射调用方法 Method方法名.invoke(类的对象,传参)

如果用下方的代码去命令执行会发现一个问题,已经可以new出相应类的对象了还有必要通过反射再调用方法么

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import java.lang.Class;
import java.lang.reflect.*;

class Data {
public void print() {
System.out.println("成功调用print方法");
}
}

public class Main {
public static void main(String[] args) throws Exception {
Data d = new Data();//声明Data类对象
Class data = d.getClass();//获取类
Method m = data.getMethod("print");//获取方法
m.invoke(d,null);//执行方法
}
}

反射调用方法

使用invoke方法反射调用指定方法时,需要传入一个类的对象

在实际的环境中,可能没法通过new来声明一个对象

此时也需要通过反射,先获取该类的构造方法,再通过构造方法创建一个对象

作用 代码
获取类的构造方法,并返回其对象 Class对象名.getConstructor()
通过构造方法创建类对象 Constructor对象名.newInstance()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.lang.Class;
import java.lang.reflect.*;

class Data {
public Data(){
//构造方法
}
public void print() {
System.out.println("成功调用print方法");
}
}

public class Main {
public static void main(String[] args) throws Exception {
Class data = Class.forName("Data");//获取类
Method m = data.getMethod("print");//获取方法
Constructor c = data.getConstructor();//获取该类的构造方法
Object obj = c.newInstance();//声明该类的对象
m.invoke(obj);//执行方法
}
}

Java反射与命令执行

通过java.io.IOException实现命令执行

如果是通过java.io.IOException实现命令执行时,需要获取Runtime类构造方法的对象

但它的构造方法被private修饰了,无法直接获取

但Runtime类存在一个public的方法getRuntime可以直接返回Runtime类的对象

所以就不需要通过getConstructor获取构造方法来创建对象,而是通过Runtime的getRuntime方法

1
2
3
4
5
6
7
8
9
10
11
12
import java.lang.Class;
import java.lang.reflect.*;

public class Main {
public static void main(String[] args) throws Exception {
Class c = Class.forName("java.lang.Runtime");//获取类
Method m1 = c.getMethod("getRuntime");//获取getRuntime方法,用于创建对象
Method m2 = c.getMethod("exec",String.class);//获取exec方法,用于执行命令
Object obj = m1.invoke(null,null);//创建对象
m2.invoke(obj,"calc");//反射调用
}
}

通过java.lang.ProcessBuilder实现命令执行

ProcessBuilder类中,其构造方法需要传入一个List类型的数据,用来设置需要执行的命令

获取构造方法时,需要指定类型为List

在创建相应对象时,也需要传入一个List用来设置需要执行的命令信息

作用 代码
创建List Arrays.asList(数据)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import java.lang.Class;
import java.lang.reflect.*;
import java.util.Arrays;
import java.util.List;

public class Main {
public static void main(String[] args) throws Exception {
Class c = Class.forName("java.lang.ProcessBuilder");//获取类
Method m = c.getMethod("start");//获取start方法,用于执行命令
Constructor con = c.getConstructor(List.class);//获取构造方法
Object obj = con.newInstance(Arrays.asList("calc"));//创建对象
m.invoke(obj);//反射调用
}
}

参考

https://blog.csdn.net/sinat_38259539/article/details/71799078

https://docs.oracle.com/javase/8/docs/api/java/io/IOException.html

https://blog.csdn.net/u013256816/article/details/54603910

https://zhuanlan.zhihu.com/p/343034495

https://www.cainiaojc.com/java/java-reflection.html

https://xz.aliyun.com/t/12446

https://www.cnblogs.com/Nestar/p/17335689.html

https://github.com/wa1ki0g/javasec

https://mp.weixin.qq.com/s/5XL8aOZYtYm8F24TlTTUUQ

https://mp.weixin.qq.com/s/B8iNY5DS7s95WOTCTEK5PA