2021.9.9 process类 、Java反射、监控目录、JSONObject

目录

一、process类

1.创建进程对象

2.process方法

二、Java反射

1.Class类

2.Constructor类

3.field类

4.Method类

三、监控目录

1.Java中的用法(简略)

2.android中的用法-FileObserver类

2.1 概念 

2.2 使用步骤(FileObserver 创建了一个线程):

2.3 实例代码:

四、Random类


一、process类

JAVA 中 process 类的使用

 Process是一个抽象类  封装了一个进程

1.创建进程对象

创建 process

方法1:
Process p =  Runtime.getRuntime().exec(cmd);
cmd 是字符串类型 也可以是字符串类型的数组 内容就是 命令行

方法2:
Process p =ProcessBuilder.start();

Process 类提供了子进程的输入流,子进程的输出流子进程的输入流,等待进程完成,检查进程的推出状态以及销毁进程的方法;创建的子进程没有自己的控制台或终端,其所有的io操作都是通过(输入流、输出流、错误流)重定向到父进程中。

2.process方法

destroy() #杀掉子进程。
 exitValue() #返回子进程的出口值。
 InputStream getErrorStream() #获得子进程的错误流。
 InputStream getInputStream()  #获得子进程的输入流。
 OutputStream getOutputStream() #获得子进程的输出流。
 waitFor() #导致当前线程等待,如果必要,一直要等到由该 Process 对象表示的进程已经终止。

二、Java反射

反射是框架设计的灵魂

(使用的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码))

反射就是把java类中的各种成分映射成一个个的Java对象
例如:一个类有:成员变量、方法、构造方法、包等等信息,利用反射技术可以对一个类进行解剖,把个个组成部分映射成一个个对象。
使用反射的步骤:

(1.得到class类对象。

(2.通过class对象得到 成员变量、方法、构造方法、包的对象。

(3.通过成员变量、方法的对象修改自己访问权限  ,通过构造方法对象得到类对象,下面调用成          员变量、方法时需要用到类对象。

(4.通过成员变量、方法对象的方法访问。

例子-成员变量(全):

package fanshe.field;
 
public class Student {
	public Student(){
		
	}
	//**********字段*************//
	public String name;
	protected int age;
	char sex;
	private String phoneNum;
	
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + ", sex=" + sex
				+ ", phoneNum=" + phoneNum + "]";
	}
	
	
}

package fanshe.field;
import java.lang.reflect.Field;
/*
 * 获取成员变量并调用:
 * 
 * 1.批量的
 * 		1).Field[] getFields():获取所有的"公有字段"
 * 		2).Field[] getDeclaredFields():获取所有字段,包括:私有、受保护、默认、公有;
 * 2.获取单个的:
 * 		1).public Field getField(String fieldName):获取某个"公有的"字段;
 * 		2).public Field getDeclaredField(String fieldName):获取某个字段(可以是私有的)
 * 
 * 	 设置字段的值:
 * 		Field --> public void set(Object obj,Object value):
 * 					参数说明:
 * 					1.obj:要设置的字段所在的对象;
 * 					2.value:要为字段设置的值;
 * 
 */
public class Fields {
 
		public static void main(String[] args) throws Exception {
			//1.获取Class对象
			Class stuClass = Class.forName("fanshe.field.Student");
			//2.获取字段
			System.out.println("************获取所有公有的字段********************");
			Field[] fieldArray = stuClass.getFields();
			for(Field f : fieldArray){
				System.out.println(f);
			}
			System.out.println("************获取所有的字段(包括私有、受保护、默认的)********************");
			fieldArray = stuClass.getDeclaredFields();
			for(Field f : fieldArray){
				System.out.println(f);
			}
			System.out.println("*************获取公有字段**并调用***********************************");
			Field f = stuClass.getField("name");
			System.out.println(f);
			//获取一个对象
			Object obj = stuClass.getConstructor().newInstance();//产生Student对象--》Student stu = new Student();
			//为字段设置值
			f.set(obj, "刘德华");//为Student对象中的name属性赋值--》stu.name = "刘德华"
			//验证
			Student stu = (Student)obj;
			System.out.println("验证姓名:" + stu.name);
			
			
			System.out.println("**************获取私有字段****并调用********************************");
			f = stuClass.getDeclaredField("phoneNum");
			System.out.println(f);
			f.setAccessible(true);//暴力反射,解除私有限定
			f.set(obj, "18888889999");
			System.out.println("验证电话:" + stu);
			
		}
	}

 例子-方法(简):        

Class stuClass = Class.forName("fanshe.method.Student");
      Method m = stuClass.getMethod();
      Object obj = stuClass.getConstructor().newInstance();
      m.invoke(obj, "刘德华");

1.Class类

必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码)

1、获取Class对象的三种方式及优缺点


1.1 Class  class = Object.getClass();
1.2 任何数据类型(包括基本数据类型)都有一个“静态”的class属性
1.3 通过Class类的静态方法:forName(String  className)(常用)

优缺点:

三种方式常用第三种,第一种对象都有了还要反射干什么。第二种需要导入类的包,依赖太强,不导包就抛编译错误。一般都第三种,一个字符串可以传入也可写在配置文件中等多种方法。

2.Constructor类

1.使用步骤

a.Constructor[]  con = class.getConstructors();#得到一堆构造方法,可以选用其他方法返回特定构造方法。

b.Object object = Constructor.newInstance(Object... initargs);#即可得到原对象。

2.介绍:
1.获取构造方法:
  1).批量的方法:
public Constructor[] getConstructors():所有"公有的"构造方法
            public Constructor[] getDeclaredConstructors():获取所有的构造方法(包括私有、受保护、默认、公有)
     
  2).获取单个的方法,并调用:
public Constructor getConstructor(Class... parameterTypes):获取单个的"公有的"构造方法:
public Constructor getDeclaredConstructor(Class... parameterTypes):获取"某个构造方法"可以是私有的,或受保护、默认、公有;

  调用构造方法:
 Object object = Constructor.newInstance(Object... initargs);Object... initargs为构造方法的参数。

2、 newInstance是 Constructor类的方法(管理构造函数的类)
api的解释为:newInstance(Object... initargs) 

Object object = Constructor.newInstance(Object... initargs);Object... initargs为构造方法的参数。

可看可不看:使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例。
它的返回值是T类型,所以newInstance是创建了一个构造方法的声明类的新实例对象。并为之调用。

3.field类

使用步骤:

Class class =  forName(String  className)#略

Field f = class.getField("name");#得到name的属性对象

Object obj = class.getConstructor().newInstance();#略

f.setAccessible(true);#暴力反射,解除私有限定

f.set(obj, "18888889999");#name属性赋值

4.Method类

使用步骤:

Method method = stuClass.getMethod("show1", String.class);#

method = stuClass.getDeclaredMethod("show4", int.class);//调用制定方法(所有包括私有的),需要传入两个参数,第一个是调用的方法名称,第二个是方法的形参类型,切记是类型。

Object obj = stuClass.getConstructor().newInstance();
 method.setAccessible(true);//解除私有限定
 method.invoke(obj, 20);//需要两个参数,一个是要调用的对象(获取有反射),一个是实参
 

三、监控目录

1.Java中的用法(简略)

方法:

重要参考-监控目录

1.1、自己写代码,递归遍历
1.2、使用common-io(内部实现递归遍历)
1.3、使用WatchService(jdk提供的)
1.4、jnotify(直接调用window、Linux的api,需要拷贝dll或者so文件到对应目录下,效率非常高)

2.android中的用法-FileObserver类

2.1 概念 

        ContentObserver可以监听不同程序间指定uri或者cursor内容的变化,如果两个无网络连接的设备通过OTG线相连,并且两设备可以通过U盘路径的方式相互访问存储,那么两设备的不同应用通信可以尝试通过FileObserver或者ContentObserver来进行。

FileObserver是一个抽象类,可以创建FileObserver一个子类并且重写onEvent抽象方法来实现功能逻辑。android10(sdk版本29)之前,FileObserver有两个构造函数

public FileObserver(String path) {
    this(path, ALL_EVENTS);
}
public FileObserver(String path, int mask) {
    m_path = path;
    m_mask = mask;
    m_descriptor = -1;
}


android10开始,上面有路径参数的构造函数被废弃掉,新增了以文件和文件集合为参数的构造方法。这里需要区分当前设备版本去有效的调用路径或者文件的构造函数,否则低版本找不到相应的构造函数导致应用挂掉。

public FileObserver(@NonNull File file, @NotifyEventType int mask) {
    this(Arrays.asList(file), mask);
}
public FileObserver(@NonNull List<File> files, @NotifyEventType int mask) {
    mFiles = files;
    mMask = mask;
}

2.2 使用步骤(FileObserver 创建了一个线程):

(1.由于FileObserver是抽象类,编写类继承,重写onEnvet()函数 :class MyFileObserver extends FileObserver{.......};编写类继承

(2.实例化继承类;myFileObserver=new MyFileObserver(new File("/sdcard/test.txt")) ;

(3.开启监控:myFileObserver.startWatching();

(4.退出时要关闭监控:myFileObserver.stopWatching();

当有事件来临时会调用onEnevt()函数。

2.3 实例代码:

public class MyFileObserver extends FileObserver {
    private static final String TAG  = "MyFileObserverLog";
    public MyFileObserver(File file) {
        super(file.getAbsolutePath(), FileObserver.ALL_EVENTS);
        Log.d(TAG, "MyFileObserver: "+file.getAbsolutePath()+",,"+FileObserver.ALL_EVENTS);
    }
 
    @Override
    public void onEvent(int event,  String path) {
      Log.d(TAG, "onEvent path:"+ path+",event="+event);
      switch (event){
          case FileObserver.CREATE:
              break;
      }
    }
}
 
public class MainActivity extends AppCompatActivity {
    MyFileObserver myFileObserver;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED) {
            requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},22);
        }
        myFileObserver=new MyFileObserver(new File("/sdcard/test.txt")) ;
        myFileObserver.startWatching();
        FileProvider.getUriForFile()
    }
    @Override
    protected void onDestroy() {
        myFileObserver.stopWatching();
        super.onDestroy();
    }
}


修改文件内容,log打印如下,可以过滤对自己有用的event即可

2020-04-03 18:24:11.977 6173-6209/com.adups.myapplication D/MyFileObserverLog: onEvent path:null,event=2
2020-04-03 18:24:11.977 6173-6209/com.adups.myapplication D/MyFileObserverLog: onEvent path:null,event=32
2020-04-03 18:24:12.040 6173-6209/com.adups.myapplication D/MyFileObserverLog: onEvent path:null,event=2
2020-04-03 18:24:12.043 6173-6209/com.adups.myapplication D/MyFileObserverLog: onEvent path:null,event=2
2020-04-03 18:24:12.046 6173-6209/com.adups.myapplication D/MyFileObserverLog: onEvent path:null,event=8
上面日志对应id

public static final int MODIFY = 0x00000002;
public static final int OPEN = 0x00000020;
public static final int CLOSE_WRITE = 0x00000008;
        谷歌推荐为了保证FileObserver不被垃圾回收,最好将FileObserver保定在一个长生命周期对象上,比如sevice,或者Application。

四、Random类

在JDK的java.util包中有一个Random类,可以在指定的取值范围内随机产生数字。在Random类中有两种构造方法,如下:

Random()   //无参构造方法,用于创建一个伪随机数生成器。

Random(long seed) //有参构造方法,使用一个long类型的seed种子创建伪随机数生成器。

例子:

import java.util.Random;
public class Main{
    public static void main(String[] args)throws Exception{
        Random r=new Random();   //不传入种子
        for(int i=0;i<8;i++){
            System.out.println(r.nextInt(100));
        }
    }
}

 上边两个截图说明同样的程序运行两次得到的结果并不相同,是因为在创建Random对象时没有传入种子参数,程序会自动以当前时间为时间戳。所以每一次的运行结果都是不同的。若传入种子则相同。

五、JSONObject类

参考

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值