Java-day17(反射)

Reflection(反射)

动态语言的关键

  • 允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法
  • 提供的功能:
    在运行时判断任意一个对象所属类
    在运行时构造任意一个类的对象
    在运行时判断任意一个类所具有的成员变量和方法
    在运行时调用任意一个对象的成员变量和方法
    生成动态代理
    在这里插入图片描述


Person类

@MyAnnotation(value = "atguigu")
public class Person extends Creature<String> implements Comparable,MyInsterface{   public String name;private int age;//创建类时,尽量保留一个空参的构造器public Person() {super();System.out.print("空参");}public Person(String name) {super();this.name = name;}public Person(String name, int age) {super();this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@MyAnnotation(value = "boos")public void show() {System.out.println("I am Person");}public void display(String nation)throws Exception {System.out.println("我的国籍是= " + nation);}private Integer displays(String nation,Integer i)throws Exception {System.out.println("我的国籍是= " + nation);return i;}@Overridepublic String toString() {return "Person [name=" + name + ", age=" + age + "]";}@Overridepublic int compareTo(Object arg0) {// TODO Auto-generated method stubreturn 0;}public static void info() {System.out.println("Chianese");}class A {}
}

在这里插入图片描述

  • 没有反射之前,创建对象,调用方法,属性
@Test
public void test1() throws Exception {Person p = new Person();p.setName("HaoJie");p.setAge(22);System.out.println(p);                             p.show();p.display("中国");
}
  • 有反射之后,创建对象,调用方法,属性
@Test
public void test2() throws Exception{Class c = Person.class;//c直接指向Person实体(反射的源头java.lang.Class类)//1.创建c对应的运行时类Person类的对象Person p = (Person)c.newInstance();//2-1.通过反射获取实体的公有属性Field f1 = c.getField("name");f1.set(p,"LiYunHai");System.out.println(p);       //2-2.通过反射获取实体的私有属性Field f2 = c.getDeclaredField("age");f2.setAccessible(true);f2.set(p,26);System.out.println(p);  //通过反射调用运行时实体(类)的指定的方法Method m1 = c.getMethod("show");m1.invoke(p);Method m2 = c.getMethod("display",String.class);m2.invoke(p,"China");		
}

1.理解Class类并实例化Class类对象

在这里插入图片描述

  • 类的具体实现:
    在这里插入图片描述

    创建类,通过编译(javac.exe),生产字节码文件,之后通过java.exe加载(JVM的类加载器完成的)字节码文件,字节码文件加载到内存中,就是一个运行时类,存在缓冲区中。这个运行时类本身就是一个Class的实例
    在这里插入图片描述

  • 每一个运行时类只加载一次

  • 有Class的实例,就可以进行如下操作:

     //*创建对应的运行时类的对象//获取对应的运行时类的完整结构(属性,方法,构造器,内部类。。。)//*调用对应运行时类的指定的结构(属性,方法,构造器)//反射的应用:动态代理
    

获取Class的实例(掌握3种)

@Test
public void test4() throws ClassNotFoundException {//1.调用运行时类本身的.class属性Class clazz = Person.class;System.out.println(clazz.getName());                Class clazz1 = String.class;System.out.println(clazz1.getName());System.out.println();//2.通过运行时类的对象获取Person p = new Person();Class clazz2  = p.getClass();System.out.println(clazz2.getName());//3.通过Class的静态方法获取String classname = "java.lang.String";Class clazz3 = Class.forName(classname);System.out.println(clazz3.getName());//4.(了解)通过类的加载器ClassLoader classLoader = this.getClass().getClassLoader();Class clazz4 = classLoader.loadClass(classname);System.out.println(clazz4.getName());System.out.println(clazz1 == clazz3);//trueSystem.out.println(clazz1 == clazz2);//falseSystem.out.println(clazz1 == clazz4);//true
}

在这里插入图片描述
例:

@Test	public void test5() throws IOException {ClassLoader loader1 = ClassLoader.getSystemClassLoader();          System.out.println(loader1);//获取ClassLoader类的加载类AppClassLoaderClassLoader loader2 = loader1.getParent();System.out.println(loader2);//ExtClassLoaderClassLoader loader3 = loader2.getParent();System.out.println(loader3);//null(核心类库及引导类无法获取)Class clazz1 = Person.class;ClassLoader loader4 = clazz1.getClassLoader();System.out.println(loader4);//AppClassLoader}
	//掌握如下:查找包下的文件中的部分内容ClassLoader loader5 = this.getClass().getClassLoader();                  InputStream is = loader5.getResourceAsStream("hello.txt");//查找工程下的文件中的部分内容//FileInputStream is = new FileInputStream(new File("hello.txt"));Properties txt = new Properties();txt.load(is);String name = txt.getProperty("user");System.out.println(name);String password = txt.getProperty("password");System.out.println(password);

2.在运行时创建类对象并获取类的完整结构

在这里插入图片描述
例:

@Testpublic void test1() throws Exception {String className = "Person";                       Class clazz = Class.forName(className);  //创建对应的运行类的对象//要求:1.对应的运行时类要有空参的构造器;2.构造器的权限应在缺省(及以上)Object obj = clazz.newInstance();Person p = (Person)obj;System.out.print(p);  }@Test//构造器public void test2() throws ClassNotFoundException {String className = "Person";  Class clazz = Class.forName(className);  //getDeclaredConstructors():获取本身类所有的构造器Constructor[] cons = clazz.getDeclaredConstructors();for(Constructor c : cons) {  System.out.println(c);  }}
获取运行时类的方法
@Testpublic void test1() {Class clazz = Person.class;//1.getMethods():获取运行时类及其父类中所有声明为public的方法Method[] m1 = clazz.getMethods();for(Method m : m1) {       System.out.println(m);}System.out.println();//2.获取运行时类本身声明的所有方法Method[] m2 = clazz.getDeclaredMethods();for(Method m : m2) {System.out.println(m);}System.out.println();System.out.println();}
获取对应的运行时类的属性
@Testpublic void test1() {Class clazz = Person.class;//getFields():只能获取运行时类及其父类中声明为public的属性Field[] fields = clazz.getFields();for(int i = 0;i < fields.length;i++) {System.out.println(fields[i]);        }System.out.println();//2.getDeclaredFields():获取运行时类本身声明的所有属性Field[] fields1 = clazz.getDeclaredFields();for(Field f : fields1) {System.out.println(f.getName());}}
获取属性各个部分的内容(权限修饰符 变量类型 变量名)
@Testpublic void test2() {Class clazz = Person.class;Field[] fields = clazz.getDeclaredFields();for(Field f : fields) {//1.获取属性的权限修饰符int i = f.getModifiers();String str = Modifier.toString(i);System.out.print(str + " ");      //2.获取属性的类型Class type = f.getType();System.out.print(type.getName() + " ");//3.获取属性名System.out.print(f.getName());System.out.println();}}
注解 权限修饰符 返回值类型 方法名 形参列表 异常
@Testpublic void test2() {Class clazz = Person.class;Method[] m1 = clazz.getDeclaredMethods();for(Method m : m1) {   //1.注解Annotation[] ann = m.getAnnotations();for(Annotation an : ann) {System.out.println(an);}//2.权限修饰符String str = Modifier.toString(m.getModifiers());System.out.print(str + " ");//3.返回值类型Class returnType = m.getReturnType();System.out.print(returnType.getName() + " ");//4.方法名System.out.print(m.getName());//5.形参列表System.out.print("(");Class[] params = m.getParameterTypes();for(int i = 0;i < params.length;i++) {System.out.print(params[i].getName() + " args-" + i + " ");}System.out.print(")");//6.异常类型Class[] exps = m.getExceptionTypes();if(exps.length != 0) {System.out.print("throws ");}for(int i = 0;i < exps.length;i++) {System.out.print(exps[i].getName());}			System.out.println();}}

在这里插入图片描述

import java.lang.annotation.Retention;         
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;
@Target({TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {String value();
}

带泛型的类

public class Creature<T> {public double weight; public void breath() {System.out.println("呼吸");}
}

接口

import java.io.Serializable;public interface MyInsterface extends Serializable{}

继承,实现接口等

@MyAnnotation(value = "atguigu")
public class Person extends Creature<String> implements Comparable,MyInsterface{  public String name;private int age;//创建类时,尽量保留一个空参的构造器public Person() {super();System.out.print("空参");}public Person(String name) {super();this.name = name;}public Person(String name, int age) {super();this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@MyAnnotation(value = "boos")public void show() {System.out.println("I am Person");}public void display(String nation)throws Exception {System.out.println("我的国籍是= " + nation);}private Integer displays(String nation,Integer i)throws Exception {System.out.println("我的国籍是= " + nation);return i;}@Overridepublic String toString() {return "Person [name=" + name + ", age=" + age + "]";}@Overridepublic int compareTo(Object arg0) {// TODO Auto-generated method stubreturn 0;}public static void info() {System.out.println("Chianese");}class A {}
}

测试

import java.lang.annotation.Annotation;             
import java.lang.reflect.ParameterizedType; 
import java.lang.reflect.Type; import org.junit.Test;public class TestOther {@Test//1.获取运行时类的父类public void test1() {Class clazz = Person.class;Class superClass = clazz.getSuperclass();System.out.println(superClass);//class Creature }@Test//2.获取带泛型的父类public void test2() {Class clazz = Person.class;Type type = clazz.getGenericSuperclass();System.out.println(type);//Creature<java.lang.String> }@Test//3.获取父类的泛型public void test3() {Class clazz = Person.class;Type type = clazz.getGenericSuperclass();ParameterizedType param = (ParameterizedType)type; Type[] ars = param.getActualTypeArguments(); System.out.println(((Class)ars[0]).getName()); }@Test//获取实现的接口public void test4() {Class clazz = Person.class;Class[] interfaces = clazz.getInterfaces(); for(Class i : interfaces) { System.out.println(i); }}@Test//获取所在的包public void test5() {Class clazz = Person.class;Package pack = clazz.getPackage();System.out.println(pack); }@Test//获取注解public void test6() {Class clazz = Person.class;Annotation[] anns = clazz.getAnnotations();for(Annotation a : anns) {System.out.println(a); }}
}

3.通过反射调用类的指定方法,指定属性

调用指定构造器,创建对象
@Test//public void test3() throws Exception {String className = "Person";    Class clazz = Class.forName(className);Constructor cons = clazz.getDeclaredConstructor(String.class,int.class);cons.setAccessible(true);Person p = (Person)cons.newInstance("李福根",56);System.out.println(p);}
调用运行时类中指定的属性
@Testpublic void test3() throws Exception {Class clazz = Person.class;//1.获取指定的属性//getField(String fielName):获取运行时类中声明为public类型的指定属性名为fielName的属性Field name = clazz.getField("name");//2.创建运行时类的对象Person p = (Person)clazz.newInstance();System.out.println(p);        //3.将运行时指定的属性赋值name.set(p, "Jame");System.out.println(p);System.out.println();//getDeclaredField(String fielName):获取运行时类中指定属性名为fielName的属性Field age = clazz.getDeclaredField("age");//私有属性不能直接用getField来调//由于权限修饰符的限制,为保证可以给属性赋值,需要在操作前使此属性可被操作(缺省状态下,可不用)age.setAccessible(true);age.set(p, 25);System.out.println(p);}
调用运行时类的指定方法
@Testpublic void test3() throws Exception {Class clazz = Person.class;//getMethod(String methodName,Class .. params):获取运行时类中声明为public的指定方法Method m1 = clazz.getMethod("show");Person p = (Person)clazz.newInstance();//调用指定的方法:Object invoke(Object obj,Object ... obj)            Object returnVal = m1.invoke(p);//方法本身无返回值,就显示为nullSystem.out.println(returnVal);Method m2 = clazz.getMethod("toString");Object returnVal1 = m2.invoke(p);System.out.println(returnVal1);//方法本身有返回值,就显示为方法的返回值//调用静态的方法Method m3 = clazz.getMethod("info");m3.invoke(Person.class);//不需要对象//getDeclaredMethod(String methodName,Class .. params):获取运行时类中声明的指定方法Method m4 = clazz.getDeclaredMethod("displays",String.class,Integer.class);m4.setAccessible(true);Object returnVal2 = m4.invoke(p,"CNN",10);//调用方法System.out.println(returnVal2);//返回值}

4.动态代理与AOP

静态代理

package Proxy;     
//接口
interface ClothFactory{void productCloth();
}
//被代理类
class NikeClothFactory implements ClothFactory{@Overridepublic void productCloth() {System.out.println("Nike工厂开工了!");	}
}//代理类
class ProxyFactory implements ClothFactory{ClothFactory cf;//创建代理类的对象时,实际传入一个被代理类的对象public ProxyFactory(ClothFactory cf) {this.cf = cf;}@Overridepublic void productCloth() {System.out.println("代理开始,收专利费了!");cf.productCloth();}}
public class TestCiothProduct {public static void main(String[] args) {	NikeClothFactory nike = new NikeClothFactory();//被代理类ProxyFactory proxy = new ProxyFactory(nike);//代理类proxy.productCloth();
}
}
动态代理

在这里插入图片描述
在这里插入图片描述

package Proxy;  import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;//动态代理
interface Subject{void action();
}
//被代理类
class ReaSubject implements Subject{public void action() {System.out.println("我是被代理类,好囧ing");}
}class MyInvocationHandler implements InvocationHandler{Object obj;//实现接口的被代理类对象的声明//给被代理的对象实例化;返回一个代理类的对象声明public Object blind(Object obj) {this.obj = obj;return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this);}@Override//当通过代理类的对象发起被重写的方法的调用时,都会转换为对如下invoke方法的调用public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//method方法的返回值是returnValSystem.out.println("代理------");Object returnVal = method.invoke(obj, args);return returnVal;}
}
public class dongProxy {public static void main(String[] args) {//1.被代理类的对象ReaSubject real = new ReaSubject();//2.创建实现InvocationHandler接口的类对象MyInvocationHandler handler = new MyInvocationHandler();//3.调用blind()方法,动态的返回一个同样实现了real所在类实现的接口Subject的代理类的对象Object obj = handler.blind(real);Subject sub = (Subject)obj;//此时的sub就是代理类的对象sub.action();//跳转到InvocationHandler接口的实现类的invoke()方法的调用//例NikeClothFactory nike = new NikeClothFactory();//被代理类ClothFactory proxyCloth = (ClothFactory)handler.blind(nike);//proxyCloth即为代理类的对象proxyCloth.productCloth();}
}
动态代理与AOP

在这里插入图片描述
在这里插入图片描述
例:

package com.al.java;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;interface Human{void info();void fly();   
}
//被代理类
class SuperMan implements Human{public void info() {System.out.println("我是超人");}public void fly() {System.out.println("I believe I can fly!");}
}
class HumanUtil{public void method1() {System.out.println("========方法一======");}public void method2() {System.out.println("========方法二======");}
}class MyInvocationHandler implements InvocationHandler{Object obj;public void setObject(Object obj) {this.obj = obj;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {HumanUtil h = new HumanUtil();h.method1();Object returnval = method.invoke(obj, args);h.method2();return returnval;}}class MyProxy{//动态的创建一个代理类对象public static Object getProxyInstance(Object obj) {MyInvocationHandler handler = new MyInvocationHandler();handler.setObject(obj);return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),handler);}
}public class TestAOP {public static void main(String[] args) {	SuperMan man = new SuperMan();//创建被代理类对象Object obj = MyProxy.getProxyInstance(man);//返回代理类对象Human hu = (Human)obj;hu.info();//通过代理类的对象调用重写的抽象方法System.out.println();hu.fly();}
}

运行示例
请添加图片描述
感谢大家的支持,关注,评论,点赞!
参考资料:
尚硅谷宋红康20天搞定Java基础下部

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/141477.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

分享从零开始学习网络设备配置--任务3.7 使用动态路由RIPv2实现网络连通

任务描述 某公司随着规模的不断扩大&#xff0c;路由器的数量开始有所增加。网络管理员发现原有的静态路由已经不适合现在的公司&#xff0c;实施动态路由RIPv2协议配置&#xff0c;实现网络中所有主机之间互相通信。 在路由器较多的网络环境中&#xff0c;手工配置静态路由…

回归预测 | MATLAB实现基于RF-Adaboost随机森林结合AdaBoost多输入单输出回归预测

回归预测 | MATLAB实现基于RF-Adaboost随机森林结合AdaBoost多输入单输出回归预测 目录 回归预测 | MATLAB实现基于RF-Adaboost随机森林结合AdaBoost多输入单输出回归预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 1.MATLAB实现基于RF-Adaboost随机森林结合…

云安全之访问控制介绍

访问控制技术背景 信息系统自身的复杂性、网络的广泛可接入性等因素&#xff0c;系统面临日益增多的安全威胁&#xff0c;安全问题日益突出&#xff0c;其中一个重要的问题是如何有效地保护系统的资源不被窃取和破坏。 访问控制技术内容包括访问控制策略、访问控制模型、访问…

力扣26:删除有序数组中的重复项

26. 删除有序数组中的重复项 - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 给你一个 非严格递增排列 的数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使每个元素 只出现一次 &#xff0c;返回删除后数组的新长度。元素的 相对顺序 应该保持 …

混合Rollup:探秘 Metis、Fraxchain、Aztec、Miden和Ola

1. 引言 混合Rollup为新的以太坊L2扩容方案&#xff0c;其分为2大类&#xff1a; 将乐观与ZK技术结合的混合Rollup同时支持公开智能合约 和 私人智能合约 的混合Rollup 本文将重点关注Metis、Fraxchain、Aztec、Miden和Ola这五大项目。 2. 何为混合Rollup&#xff1f; 混合…

el-table实现穿梭功能

第一种 <template><el-row :gutter"20"><el-col :span"10"><!-- 搜索 --><div class"search-bg"><YcSearchInput title"手机号" v-model"search.phone" /><div class"search-s…

Spring面试题21:说一说Spring的@Required注解和@Qualifier注解

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:说一说Spring的@Required注解 @Required ,用于标记在注入的属性上。它表示被注解的属性在配置 Bean 的时候是必需的,如果没有正确配置,则会抛出…

C# OpenCvSharp 基于直线检测的文本图像倾斜校正

效果 项目 代码 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using OpenCvSharp;namespace OpenCvSharp_基于直线检测的文…

一文了解亚马逊云科技适用于 Amazon Lightsail 的托管数据库

Amazon Lightsail 是亚马逊云科技提供的一种易上手使用、月度价格经济实惠&#xff0c;并包括了计算实例、容器、存储、数据库的虚拟专用服务器。在创建时可以进行业务蓝图选择&#xff0c;可选择包含多种操作系统&#xff08;Linux/Windows 等&#xff09;或操作系统加上典型应…

深入剖析Redis系列- Redis数据结构之哈希

1.11.5哈希类型(hash) Redis的hash 是一个string类型的key和value的映射表&#xff0c;这里的value是一系列的键值对&#xff0c;hash特别适合用于存储对象。 哈希类型的数据操作总的思想是通过key和field操作value&#xff0c;key是数据标识&#xff0c;field是域&#xff0c;…

“全景江西·南昌专场”数字技术应用场景发布会 | 万广明市长莅临拓世集团展位,一览AIGC科技魅力

随着数字技术的迅猛发展&#xff0c;传统产业正在发生深刻的变革&#xff0c;新兴产业蓬勃兴起。但要想实现数字经济超常规发展&#xff0c;就要在数字产业化上培育新优势&#xff0c;大力实施数字经济核心产业提速行动&#xff0c;加快推进“一核三基地”建设。在这个数字经济…

[vulntarget靶场] vulntarget-c

靶场地址&#xff1a; https://github.com/crow821/vulntarget 拓扑结构 信息收集 主机发现 netdiscover -r 192.168.111.0/24 -i eth0端口扫描 nmap -A -sC -v -sV -T5 -p- --scripthttp-enum 192.168.111.131访问80端口&#xff0c;发现为Laravel v8.78.1框架 vulmap探测…

打造本地紧密链接的开源社区——KCC@长沙开源读书会openKylin爱好者沙龙圆满举办...

2023年9月9日&#xff0c;由开源社联合 openKylin 社区举办的 KCC长沙开源读书会&openKylin 爱好者沙龙&#xff0c;在长沙圆满举办。这是 KCC长沙首次正式进入公众视野&#xff0c;开展开源交流活动&#xff0c;也是 openKylin 社区长沙首场线下沙龙。长沙地区及其周边的众…

浏览器截图扩展增加快捷键

Tabshot – 下载 &#x1f98a; Firefox 扩展&#xff08;zh-CN&#xff09; 最近一个用户找到我&#xff0c;想要这个浏览器扩展有一个快捷键截图功能。 我找了一下&#xff0c;发现火狐扩展的确支持快捷键 研究源码 about:support 配置文件夹&#xff0c;打开文件夹。 附…

uniapp实现点击按钮分享给好友

<button class"share" open-type"share">分享</button>import {onLoad,onShareAppMessage,onShareTimeline} from dcloudio/uni-app onLoad(() > {//设置Menus菜单&#xff0c;使 发送给朋友/分享到朋友圈 两个按钮可以使用wx.showShareMen…

Ubuntu 安装Nacos

1、官网下载最新版nacos https://github.com/alibaba/nacos/releases 本人环境JDK8&#xff0c;Maven3.6.3&#xff0c;启动Nacos2.2.1启动失败&#xff0c;故切换到2.1.0启动成功 2、放到服务器目录下&#xff0c;我的在/home/xxx/apps下 3、解压 $ tar -zxvf nacos-serve…

安装docker、docker-compose

安装docker、docker-compose 文章目录 安装docker、docker-compose一、切换国内镜像源二、安装docker三、安装docker-compose 一、切换国内镜像源 vi /etc/docker/daemon.json {"registry-mirrors": ["https://registry.hub.docker.com","http://hu…

【蓝桥杯选拔赛真题63】Scratch云朵降雨 少儿编程scratch图形化编程 蓝桥杯选拔赛真题解析

目录 scratch云朵降雨 一、题目要求 编程实现 二、案例分析 1、角色分析

【用MyEclipse2017创建一个Hibernate Web登录项目】

用MyEclipse2017创建一个Hibernate Web登录项目 靠手工实现JavaBean/JDBC的系统 Hibernate自动生成了所需的JavaBean&#xff0c;也取代了原JDBC的功能&#xff01;可简单形象地理解为&#xff1a;Hibernate&#xff1d;JavaBean&#xff0b;JDBC 1、创建一个Java EE Web项目…

开机自启动Linux and windows

1、背景 服务器由于更新等原因重启&#xff0c;部署到该服务上的响应的应用需要自启动 2、Linux 2.1 方式一 编写启动应用的sh脚本授权该脚本权限 chmod 777 xxx.sh 修改rc.loacl 位置&#xff1a;/etc/rc.local 脚本&#xff1a;sh /home/xxxx.sh & 授权rc.local …