一篇了解Java反射

反射

image-20220322144346557

首先从运行原理了解为什么要用反射,当我们执行一段代码时,代码经过javac编译得到.class的字节码文件,再经过类加载器的loadClass()方法创建Class类对象到堆中;当我们实例化一个对象时,该对象会自动匹配到对应堆中的Class类对象,进而调用方法,操作属性等。至此程序结束。

但通过上述方式,我们写好程序运行后,如果突然需要加载另一个类时,就需要停止运行并要写一段代码去实例化新需求的类,对服务器来说会造成一定的影响;这时就体现出了反射的优势,反射机制可以通过修改配置文件,而无需修改源码对类进行重新加载。

反射是动态获取信息及动态调用对象方法的方式,Java本身是一种静态语言,而经过反射后让Java有了一定的动态性,变为一种“准动态语言”。

反射实例理解

通过外部文件配置,在不修改源码的情况下,来控制程序反射实例看不懂的话,后边自Class类开始会有各方法的分布介绍

A.java

package Sentiment.refelction;

public class A {
    private String name="refelction";
    public int age=10;
    public void a(){
        System.out.println("this is =>A");
    }
    public void b(){
        System.out.println("this is =>B");
    }
}

re.properties(配置文件)

path=Sentiment.refelction.A
method=a

此时如果我们想调用a()方法,有如下几种方法:

传统方式

A cat = new A();
cat.a();

I/O流根据配置文件读取

该方式读取后由于path类型为String,所以无法正常读取到我们的类方法

Properties properties = new Properties();
properties.load(new FileInputStream("re.properties"));
String path = properties.get("path").toString(); //Sentiment.refelction.A
String method = properties.get("method").toString(); // a
new path().a();   //报错

反射

这时就可以通过反射将String类型的path,转为Class类型的对象进行调用

//(1) 获取Class类型的对象c1
Class c1 = Class.forName(path);
//System.out.println(c1);
//(2) 通过c1 得到加载的类 Sentiment.refelction.A的对象实例
Object o = c1.newInstance();
System.out.println("o的运行类型是:"+o.getClass());
//(3)通过c1 得到加载的类Sentiment.refelction.A 的method的方法对象"a"
Method method1 =c1.getMethod(method); 
//(4)通过method1 调用方法对象来实现调用方法
method1.invoke(o);//传统方法 对象.方法() ,反射 方法.invoke(对象)

此时如果用户,想要调用A.java中的b()方法,就体现出了反射的优势。

还是先看传统方法,需要将a改为b,即修改源码

A cat = new A();
cat.b();  

而反射机制则可以通过修改配置文件,而无需修改源码。在用户需求较大时,可以完全体现反射优势

path=Sentiment.refelction.A
method=a

反射优缺点

优点

可以动态的创建和使用对象(也是框架底层核心).使用灵活,没有反射机制,框架技术就失去底层支撑。

缺点

使用反射基本是解释执行,对执行速度有影响.

运行同一内容耗时对比

image-20220322160327354

Class类

介绍

1.Class也是类,也继承Object类

image-20220323094648819

2.Class类对象不是new出来的,而是系统创建的 (都是通过Classloader类创建的)

3.每个类的Class类对象,在内存中只有一份,因为类只加载一次

public class Class01 {
    public static void main(String[] args) throws ClassNotFoundException {
        //每个类的Class类对象,在内存中只有一份,因为类只加载一次
        Class c1 = Class.forName("Sentiment.refelction.A");
        Class c2 = Class.forName("Sentiment.refelction.A");
        System.out.println(c1.hashCode());
        System.out.println(c2.hashCode());
    }
}

image-20220323095049247

4.每个类的实例都会记得自己是由哪个Class 实例所生成(如最开始的运行原理图所示Cat会找到对应的Cat类对象)

5.通过Class对象可以完整地得到一个类的完整结构,通过一系列API

image-20220323100818374

6.Class对象是存放在堆的

7.类的字节码二进制数据,是放在方法区的,有的地方称为类的元数据(包括方法代码变量名,方法名,访问权限等等)

Class类常用方法

Car.java

package Sentiment.refelction;

public class Car {
    public String brand="宝马";
    public int price = 5000000;
    public String color = "白色";

    @Override
    public String toString() {
        return "Car{" +
                "brand='" + brand + '\'' +
                ", price=" + price +
                ", color='" + color + '\'' +
                '}';
    }
}

Class02.java

package Sentiment.refelction;

import java.lang.reflect.Field;

public class Class02 {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        String path="Sentiment.refelction.Car";
        //1. 获取Car类对应的Class对象
        Class c1 = Class.forName(path);
        //2. 输出c1
        System.out.println(c1); //显示c1对象是哪个类的Class对象 Sentiment.refelction.Car
        System.out.println(c1.getClass());//输出c1运行类型 java.lang.Class
        //3.获取包名
        System.out.println(c1.getPackage().getName());
        //4.得到类的全路径
        System.out.println(c1.getName());
        //5. 通过c1创建对象实例
        Car car = (Car)c1.newInstance();
        System.out.println(car);    //输出car时自动调用toString()方法
        //6. 通过反射获取属性
        Field brand = c1.getField("brand");
        System.out.println(brand.get(car));
        //7.通过反射给属性赋值
        brand.set(car,"奔驰");
        System.out.println(brand.get(car));
        //8.获取所有属性及属性值
        Field[] fields = c1.getFields();
        for(Field f : fields){
            System.out.print(f.getName()+":");  //属性名
            System.out.print(f.get(car)+" ");   //属性值
        }
    }
}

获取Class类对象

1.已知一个类的全类名,且该类在类路径下,可通过Class类的静态方法forName()获取,可能跑出ClassNotFoundException

Class c1=Class.forName("Sentiment.refelction.Car")

多用于配置文件,读取类全路径,加载类

2.若已知具体的类,通过类的class获取,该方式最为安全可靠,程序性能最高

Class c2=Car.class

多用于参数传递,比如通过反射得到对应构造器对象

3.前提:已知某个类的实例,调用该实例的getClass()方法获取Class对象

Car car = new Car();
Class c3 = car.getClass();

多用于通过创建好的对象,获取Class对象.

4.通过类加载器来获取Class类对象

//(1)先得到加载器
 ClassLoader classLoader = car.getClass().getClassLoader();
//(2)通过类加载器得到Class对象
 Class c4 =classLoader.loadClass(path);

5.基本数据(int, char, boolean,float,double,byte,long,short)按如下方式得到Class类对象

Class c5 = 基本数据类型.class

6.基本数据类型对应的包装类,可以通过type得到Class类对象

Class c6 = 包装类.type

GetClass.java

package Sentiment.refelction;

public class GetClass {
    public static void main(String[] args) throws ClassNotFoundException {
        //1.Class.forName)
        String path="Sentiment.refelction.Car"; //通过读取配置文件获取
        Class c1 = Class.forName(path);
        System.out.println(c1);
        //2.类名.class,用于参数传递
        Class c2 = Car.class;
        System.out.println(c2);
        //3.对象.getClass(),用于有对象实例
        Car car = new Car();
        Class c3 = car.getClass();
        System.out.println(c3);
        //4.通过类加载器来获取Class类对象
        //(1)先得到加载器car
        ClassLoader classLoader = car.getClass().getClassLoader();
        //(2)通过类加载器得到Class对象
        Class c4 =classLoader.loadClass(path);
        System.out.println(c4);
        //5.基本数据(int, char, boolean,float,double,byte,long,short)按如下方式得到Class类对象
        Class c5 = int.class;
        Class<Character> characterClass = char.class;
        //6.基本数据类型对应的包装类,可以通过type得到Class类对象
        Class<Integer> type = Integer.TYPE;
        Class<Character> type1 = Character.TYPE;
        System.out.println(type);
    }

类加载

分类

静态加载:编译时加载相关的类,如果没有该类就会报错,依赖性很强

动态加载:运行时加载需要的类,如果运行时不用该类则不回加载,也不会报错,降低了依赖性

先看看常规的静态加载方法ClassLoad.java

package Sentiment.refelction;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Scanner;

public class ClassLoad {
    public static void main(String[] args) throws Exception {
        Scanner scanner = new Scanner(System.in);
        String key = scanner.next();
        switch (key){
            case "1":
                Dog dog = new Dog();
                dog.cry();
                break;
            case "2":
                System.out.println("ok");
                break;
            default:
                System.out.println("Do nothing!");
    }}
}

当编译时,即使还没有输入key=1,也就是还没有调用new Dog()就会报错找不到该类

image-20220324111335291

而当使用动态加载,也就是反射机制时

package Sentiment.refelction;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Scanner;

public class ClassLoad {
    public static void main(String[] args) throws Exception {
        Scanner scanner = new Scanner(System.in);
        String key = scanner.next();
        switch (key){
        //静态加载
            case "1":
                //Dog dog = new Dog();
                //dog.cry();
                //break;
       //反射动态加载
            case "2":
                Class c1 = Class.forName("Person"); 
                Object o = c1.newInstance();
                Method method = c1.getMethod("hi");
                method.invoke(o);
                System.out.println("ok");
                break;
            default:
                System.out.println("Do nothing!");

    }}
}

在没有调用Person类和hi方法的情况下,可以直接执行

image-20220324111424482

当输入3时会调用default方法,并不会加载Person类,只有在key=2需要加载Person类时,才会报错

image-20220324114026260

类加载时机

当创建对象时(new) //静态加载

当子类被加载时,父类也加载 //静态加载

调用子类中的静态成员时 //静态加载

通过反射 //动态加载

通过反射获取类的结构信息

java.lang.Class类API

getName:获取全类名

getSimpleName:获取简单类名

getFields:获取所有pubulic修饰的属性,包括本类以及父类的

getDeclaredFields:获取本类中所有属性

getMethods:获取所有public修饰的方法,包含本类以及父类的(父类包括Object类)

getDeclaredMethods:获取本类中的所有方法

getConstrctors:获取所有本类的public修饰的构造器

getDeclaredConstructors:获取本类中的所有构造器

getPackage:以Package形式返回包信息

getSuperClass:以Class形式返回父类信息

getInterfaces:以Class[]形式返回接口信息

getAnnotations:以Annotation[] 形式返回注解信息

上述方法应用实例:ReflectionUtils.java

package Sentiment.refelction;

import java.lang.annotation.Annotation;
import java.lang.annotation.Documented;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ReflectionUtils {
    public static void main(String[] args) throws ClassNotFoundException {
        new ReflectionUtils().api();
    }
    public  void api() throws ClassNotFoundException {
        Class c1 = Class.forName("Sentiment.refelction.Person");//获取Class对象
        //getName:获取全类名
        System.out.println(c1.getName());
        //getSimpleName:获取简单类名
        System.out.println(c1.getSimpleName());
        //getFields:获取所有pubulic修饰的属性,包括本类以及父类的
        Field[] fields = c1.getFields();
        for (Field field : fields) {
            System.out.println("本类以及父类的属性="+field.getName());
        }
        //getDeclaredFields:获取本类中所有属性
        Field[] declaredFields = c1.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println("本类中所有属性="+declaredField.getName());
        }
        //getMethods:获取所有public修饰的方法,包含本类以及父类的(父类包括Object类)
        Method[] methods = c1.getMethods();
        for (Method method : methods) {
            System.out.println("本类以及父类的public方法="+method.getName());
        }
        //getDeclaredMethods:获取本类中的所有方法
        Method[] declaredMethods = c1.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println("本类中的所有方法="+declaredMethod);
        }
        //getConstrctors:获取所有本类的public修饰的构造器
        Constructor[] constructors = c1.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println("本类的public构造器="+constructor);
        }
        //getDeclaredConstructors:获取本类中的所有构造器
        Constructor[] declaredConstructors = c1.getDeclaredConstructors();
        for (Constructor declaredConstructor : declaredConstructors) {
            System.out.println("本类中的所有构造器= "+declaredConstructor);
        }
        //getPackage:以Package形式返回包信息
        System.out.println("包信息"+c1.getPackage());
        //getSuperClass:以Class形式返回父类信息
        System.out.println("父类的class对象= "+c1.getSuperclass());
        //getInterfaces:以Class[]形式返回接口信息
        Class[] interfaces = c1.getInterfaces();
        for (Class anInterface : interfaces) {
            System.out.println("接口信息= "+anInterface);
        }
        //getAnnotations:以Annotation[]形式返回注解信息
        Annotation[] annotations = c1.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println("注解信息= "+annotation);
        }
    }
}
interface IA{

}
interface IB{

}
class B{
    public String hobby;
    public void hi(){

    }
    public B() {
    }
}
@Deprecated
class Person extends B implements IA,IB{
     //属性
    public String name;
    protected int age;
    String job;
    private double sal;
    //方法
    public void m1(){

    }
    protected void m2(){

    }
    void m3(){

    }
    private void m4(){

    }
    //构造方法
    public Person() {
    }

    public Person(String name) {
        this.name = name;
    }
}

运行结果(各方法间用--- 分割)

Sentiment.refelction.Person
-----------------------------
Person
-----------------------------
本类以及父类的属性=name
本类以及父类的属性=hobby
-----------------------------
本类中所有属性=name
本类中所有属性=age
本类中所有属性=job
本类中所有属性=sal
-----------------------------
本类以及父类的public方法=m1
本类以及父类的public方法=hi
本类以及父类的public方法=wait
本类以及父类的public方法=wait
本类以及父类的public方法=wait
本类以及父类的public方法=equals
本类以及父类的public方法=toString
本类以及父类的public方法=hashCode
本类以及父类的public方法=getClass
本类以及父类的public方法=notify
本类以及父类的public方法=notifyAll
-----------------------------
本类中的所有方法=protected void Sentiment.refelction.Person.m2()
本类中的所有方法=void Sentiment.refelction.Person.m3()
本类中的所有方法=private void Sentiment.refelction.Person.m4()
本类中的所有方法=public void Sentiment.refelction.Person.m1()
-----------------------------
本类的public构造器=public Sentiment.refelction.Person()
本类的public构造器=public Sentiment.refelction.Person(java.lang.String)
-----------------------------
本类中的所有构造器= public Sentiment.refelction.Person()
本类中的所有构造器= public Sentiment.refelction.Person(java.lang.String)
-----------------------------
包信息package Sentiment.refelction
-----------------------------
父类的class对象= class Sentiment.refelction.B
-----------------------------
接口信息= interface Sentiment.refelction.IA
接口信息= interface Sentiment.refelction.IB
-----------------------------
注解信息= @java.lang.Deprecated()
-----------------------------

java.lang.feflect.Field类API

getModifiers:以int形式返回修饰符(默认修饰符—>0,public—>1,priva—>2,protected—>4,static—>8,final—>16。若为混合类型则相加计算
例:public+static = 1+8 = 9)

getType:以Class形式返回类型

getName:返回属性名

java.lang.reflect.Method类API

getModifiers:以int形式返回修饰符

getReturnType:以Class形式获取返回类型

getName:返回方法名

getParameterTypes:以Class[]返回参数类型数组(即形参类型)

java.lang.reflect.Constructor类API

getModifiers:以int形式返回修饰符

getName:返回方法名

getParameterTypes:以Class[]返回参数类型数组

上述三类API实例代码:ReflectionUtils02.java

package Sentiment.refelction;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ReflectionUtils02 {
    public static void main(String[] args) throws ClassNotFoundException {
        new ReflectionUtils02().api2();
    }
    public void api2() throws ClassNotFoundException {
        Class c1 = Class.forName("Sentiment.refelction.Student");//获取Class对象
        System.out.println("------------------------------");
        System.out.println("java.lang.feflect.Field类API");
        System.out.println("------------------------------");
        //getDeclaredFields:获取本类中所有属性
        Field[] declaredFields = c1.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println("本类中所有属性="+declaredField.getName()+" 该类的属性值="+declaredField.getModifiers()+" 类型是="+declaredField.getType());
        }
        System.out.println("------------------------------");
        System.out.println("java.lang.reflect.Method类API");
        System.out.println("------------------------------");
        //getDeclaredMethods:获取本类中的所有方法
        Method[] declaredMethods = c1.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println("本类中的所有方法="+declaredMethod.getName()+" 该方法的属性值="+declaredMethod.getModifiers()+" 该方法的返回类型="+declaredMethod.getReturnType());
        //方法的形参类型
            Class[] parameterTypes = declaredMethod.getParameterTypes();
            for (Class parameterType : parameterTypes) {
                System.out.println("形参类型= "+parameterType);
            }
        }
        System.out.println("------------------------------");
        System.out.println("java.lang.reflect.Constructor类API");
        System.out.println("------------------------------");
        //getDeclaredConstructors:获取本类中的所有构造器
        Constructor[] declaredConstructors = c1.getDeclaredConstructors();
        for (Constructor declaredConstructor : declaredConstructors) {
            System.out.println("本类中的所有构造器= "+declaredConstructor.getName()+" 该构造器的属性值= "+declaredConstructor.getModifiers());
            Class[] parameterTypes = declaredConstructor.getParameterTypes();
            for (Class parameterType : parameterTypes) {
                System.out.println("形参类型= "+parameterType);
            }
        }


}}
 class Student {
    //属性
    int age;
    public String name;
    private String grade;
    protected static double score;
    //方法
     public void m1(int age ,String name,double score){

     }
     protected String m2(){
        return null;
     }
     void m3(){

     }
     private void m4(){

     }
    //构造方法

     Student() {
     }

     public Student(int age) {
         this.age = age;
     }

     private Student(int age, String name, String grade) {
         this.age = age;
         this.name = name;
         this.grade = grade;
     }
 }

运行结果(以---做各类分割)

反射爆破

反射创建对象

通过public的无参构造器创建实例

Object o = c3.newInstance();

通过pulic的有参构造创建实例

Constructor constructor = c3.getConstructor(String.class); //先得到构造器
Object tana = constructor.newInstance("tana");             //创建实例,传入实参

通过非public的有参构造器创建对象

setAccessible爆破

Constructor declaredConstructor = c3.getDeclaredConstructor(int.class,String.class);  //先得到构造器
declaredConstructor.setAccessible(true);                            //爆破访问private构造器/方法/属性
Object mumu = declaredConstructor.newInstance(100, "mumu");         //创建实例,传入实参

实例代码:ReflectionCreate.java

package Sentiment.refelction;

import java.lang.reflect.Constructor;

public class ReflectionCreate {
    public static void main(String[] args) throws Exception {
        //获取类的Class对象
        Class<?> c3 = Class.forName("Sentiment.refelction.User");
        //通过public的无参构造器创建实例
        Object o = c3.newInstance();
        System.out.println(o);
        //通过pulic的有参构造创建实例
        Constructor constructor = c3.getConstructor(String.class);
        Object tana = constructor.newInstance("tana");
        System.out.println("tana = "+tana);
        //通过非public的有参构造器创建对象
        Constructor<?> declaredConstructor = c3.getDeclaredConstructor(int.class,String.class);
        declaredConstructor.setAccessible(true);
        Object mumu = declaredConstructor.newInstance(100, "mumu");;
        System.out.println("mumu = "+mumu);
    }
}
class User{
    //属性
    private int age=10;
    private String name="Sentiment";
    //构造方法
    public User() {
    }

    public User(String name) {
        this.name = name;
    }

    private User(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public String toString() {
        return "User{" + "age=" + age + ", name='" + name + '\'' + '}';
    }
}

运行结果

User{age=10, name='Sentiment'}
tana = User{age=10, name='tana'}
mumu = User{age=100, name='mumu'}

反射访问类成员

获取public属性

获取属性:Class类对象.getField(“属性值”);

修改属性值:属性.set(o,值);

输出属性值:属性.get(o);

Field age = c4.getField("age");          //age为属性名
age.set(o,100);                          //修改属性值;o为对象实例
System.out.println(age.get(o));    

获取private属性

获取属性:Class类对象.getDeclaredField(“属性值”);

爆破:属性.setAccessible(true);

Field name = c4.getDeclaredField("name");   //name为属性名
name.setAccessible(true);                   //爆破
name.set(o,"tana");                         //修改属性值,o为对象实例
System.out.println(name.get(null));         //static修饰的对象,也可以用null代替

实例代码:ReflectionCreate02.java

package Sentiment.refelction;

import java.lang.reflect.Field;

public class ReflectionCreate02 {
    public static void main(String[] args) throws Exception{
        Class c4 = Class.forName("Sentiment.refelction.human");
        Object o = c4.newInstance();
        //获取public属性
        Field age = c4.getField("age");
        age.set(o,100);                          //修改属性值
        System.out.println(age.get(o));
        //获取private属性
        Field name = c4.getDeclaredField("name");
        name.setAccessible(true);
        name.set(o,"tana");                     //修改属性值
        System.out.println(name.get(null));
    }
}
class human{
    //属性
    public int age=10;
    private static String name ="Sentiment";
    //构造器
    public human() {
    }

    @Override
    public String toString() {
        return "human{" + "age=" + age +", name"+name+'}';
    }
}

运行结果

100
tana

反射调用方法

调用public方法

获取方法:Class类对象.getMethod(“方法名”, 方法类型.class);;

调用方法:对象.invoke(实例化对象,“实参值”);

Method say1 = c5.getMethod("say1", String.class);       //say1为String类型的方法
say1.invoke(o,"Sentiment");                       

调用private方法

获取方法:Class类对象.getDeclaredMethod(“方法名”, 方法类型.class);;

调用方法:对象.invoke(实例化对象,“实参值”);

爆破:method.setAccessible(true);

Method say2 = c5.getDeclaredMethod("say2", int.class, String.class, char.class);    //say2方法及其类型
say2.setAccessible(true);
System.out.println(say2.invoke(o,10,"tana",'M'));

实例代码:ReflectionCreate03.java

package Sentiment.refelction;

import java.lang.reflect.Method;

public class ReflectionCreate03 {
    public static void main(String[] args) throws Exception{
        Class c5 = Class.forName("Sentiment.refelction.man");
        Object o = c5.newInstance();
        //调用public方法
        Method say1 = c5.getMethod("say1", String.class);
        say1.invoke(o,"Sentiment");
        //调用private方法
        Method say2 = c5.getDeclaredMethod("say2", int.class, String.class, char.class);
        say2.setAccessible(true);
        System.out.println(say2.invoke(o,10,"tana",'M'));
        System.out.println(say2.invoke(null,20,"mumu",'M'));    //静态方法可以用null代替实例对象

    }
}
class man{
    //属性
    public int age;
    private static String name;
    //构造方法
    public man() {
    }
    //方法
    public void say1(String a){
        System.out.println("this is =>"+a);
    }
    private static String say2(int a,String b, char c){
        return a+" "+b+" "+c;
    }

}

反射练习

Work1

定义个Test类,其中定义私有属性name,赋值为"xxxxxx"

Test类中创建公有方法getName()内容为return name

创建Test的Class类,并获得私有属性name,修改私有属性name的值,并调用getName()方法输出name的值

参考

Work1.java

package Sentiment.refelction;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Work1 {
    public static void main(String[] args) throws Exception{
        Class c1 = Class.forName("Sentiment.refelction.Test");
        Object o = c1.newInstance();
        Field name = c1.getDeclaredField("name");
        name.setAccessible(true);
        name.set(o,"tana");
        Method getName = c1.getMethod("getName");
        System.out.println(getName.invoke(o));

    }
}
class Test{
    private String name = "Sentiment";
    public String getName(){
        return name;
    }

}

Work2

获取java.io.File的class对象,并输出该类的所有构造器方法

通过newInstance创建File对象,在自己电脑中创建个a.txt

参考

Work2.java

package Sentiment.refelction;

import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class Work2 {
    public static void main(String[] args) throws Exception{
        Class c2 = Class.forName("java.io.File");
        Constructor[] c = c2.getDeclaredConstructors();
        for (Constructor Constructor : c) {
            System.out.println(Constructor);
        }
        //获取构造器public java.io.File(java.lang.String)
        Constructor declaredConstructor = c2.getDeclaredConstructor(String.class);
        String path="D:\\a.txt";
        //实例化类
        Object path1 = declaredConstructor.newInstance(path);
        //获取createNewFile方法
        Method createNewFile = c2.getMethod("createNewFile");
        createNewFile.invoke(path1);
        System.out.println(path1.getClass());
        System.out.println("创建文件成功:"+path);
    }
}




package Sentiment.refelction;

import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class Work2 {
    public static void main(String[] args) throws Exception{
        Class c2 = Class.forName("java.io.File");
        Constructor[] c = c2.getDeclaredConstructors();
        for (Constructor Constructor : c) {
            System.out.println(Constructor);
        }
        //获取构造器public java.io.File(java.lang.String)
        Constructor declaredConstructor = c2.getDeclaredConstructor(String.class);
        String path="D:\\a.txt";
        //实例化类
        Object path1 = declaredConstructor.newInstance(path);
        //获取createNewFile方法
        Method createNewFile = c2.getMethod("createNewFile");
        createNewFile.invoke(path1);
        System.out.println(path1.getClass());
        System.out.println("创建文件成功:"+path);
    }
}


题外话

初入计算机行业的人或者大学计算机相关专业毕业生,很多因缺少实战经验,就业处处碰壁。下面我们来看两组数据:

2023届全国高校毕业生预计达到1158万人,就业形势严峻;

国家网络安全宣传周公布的数据显示,到2027年我国网络安全人员缺口将达327万。

一方面是每年应届毕业生就业形势严峻,一方面是网络安全人才百万缺口。

6月9日,麦可思研究2023年版就业蓝皮书(包括《2023年中国本科生就业报告》《2023年中国高职生就业报告》)正式发布。

2022届大学毕业生月收入较高的前10个专业

本科计算机类、高职自动化类专业月收入较高。2022届本科计算机类、高职自动化类专业月收入分别为6863元、5339元。其中,本科计算机类专业起薪与2021届基本持平,高职自动化类月收入增长明显,2022届反超铁道运输类专业(5295元)排在第一位。

具体看专业,2022届本科月收入较高的专业是信息安全(7579元)。对比2018届,电子科学与技术、自动化等与人工智能相关的本科专业表现不俗,较五年前起薪涨幅均达到了19%。数据科学与大数据技术虽是近年新增专业但表现亮眼,已跻身2022届本科毕业生毕业半年后月收入较高专业前三。五年前唯一进入本科高薪榜前10的人文社科类专业——法语已退出前10之列。
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

“没有网络安全就没有国家安全”。当前,网络安全已被提升到国家战略的高度,成为影响国家安全、社会稳定至关重要的因素之一。

网络安全行业特点

1、就业薪资非常高,涨薪快 2022年猎聘网发布网络安全行业就业薪资行业最高人均33.77万!

img

2、人才缺口大,就业机会多

2019年9月18日《中华人民共和国中央人民政府》官方网站发表:我国网络空间安全人才 需求140万人,而全国各大学校每年培养的人员不到1.5W人。猎聘网《2021年上半年网络安全报告》预测2027年网安人才需求300W,现在从事网络安全行业的从业人员只有10W人。
img

行业发展空间大,岗位非常多

网络安全行业产业以来,随即新增加了几十个网络安全行业岗位︰网络安全专家、网络安全分析师、安全咨询师、网络安全工程师、安全架构师、安全运维工程师、渗透工程师、信息安全管理员、数据安全工程师、网络安全运营工程师、网络安全应急响应工程师、数据鉴定师、网络安全产品经理、网络安全服务工程师、网络安全培训师、网络安全审计员、威胁情报分析工程师、灾难恢复专业人员、实战攻防专业人员…

职业增值潜力大

网络安全专业具有很强的技术特性,尤其是掌握工作中的核心网络架构、安全技术,在职业发展上具有不可替代的竞争优势。

随着个人能力的不断提升,所从事工作的职业价值也会随着自身经验的丰富以及项目运作的成熟,升值空间一路看涨,这也是为什么受大家欢迎的主要原因。

从某种程度来讲,在网络安全领域,跟医生职业一样,越老越吃香,因为技术愈加成熟,自然工作会受到重视,升职加薪则是水到渠成之事。

黑客&网络安全如何学习

今天只要你给我的文章点赞,我私藏的网安学习资料一样免费共享给你们,来看看有哪些东西。

1.学习路线图

行业发展空间大,岗位非常多

网络安全行业产业以来,随即新增加了几十个网络安全行业岗位︰网络安全专家、网络安全分析师、安全咨询师、网络安全工程师、安全架构师、安全运维工程师、渗透工程师、信息安全管理员、数据安全工程师、网络安全运营工程师、网络安全应急响应工程师、数据鉴定师、网络安全产品经理、网络安全服务工程师、网络安全培训师、网络安全审计员、威胁情报分析工程师、灾难恢复专业人员、实战攻防专业人员…

职业增值潜力大

网络安全专业具有很强的技术特性,尤其是掌握工作中的核心网络架构、安全技术,在职业发展上具有不可替代的竞争优势。

随着个人能力的不断提升,所从事工作的职业价值也会随着自身经验的丰富以及项目运作的成熟,升值空间一路看涨,这也是为什么受大家欢迎的主要原因。

从某种程度来讲,在网络安全领域,跟医生职业一样,越老越吃香,因为技术愈加成熟,自然工作会受到重视,升职加薪则是水到渠成之事。

黑客&网络安全如何学习

今天只要你给我的文章点赞,我私藏的网安学习资料一样免费共享给你们,来看看有哪些东西。

1.学习路线图

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

攻击和防守要学的东西也不少,具体要学的东西我都写在了上面的路线图,如果你能学完它们,你去就业和接私活完全没有问题。

2.视频教程

网上虽然也有很多的学习资源,但基本上都残缺不全的,这是我自己录的网安视频教程,上面路线图的每一个知识点,我都有配套的视频讲解。

内容涵盖了网络安全法学习、网络安全运营等保测评、渗透测试基础、漏洞详解、计算机基础知识等,都是网络安全入门必知必会的学习内容。
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(都打包成一块的了,不能一一展开,总共300多集)

因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

如果你对网络安全入门感兴趣,那么你需要的话可以点击这里👉网络安全重磅福利:入门&进阶全套282G学习资源包免费分享!

3.技术文档和电子书

技术文档也是我自己整理的,包括我参加大型网安行动、CTF和挖SRC漏洞的经验和技术要点,电子书也有200多本,由于内容的敏感性,我就不一一展示了。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

如果你对网络安全入门感兴趣,那么你需要的话可以点击这里👉网络安全重磅福利:入门&进阶全套282G学习资源包免费分享!

4.工具包、面试题和源码

“工欲善其事必先利其器”我为大家总结出了最受欢迎的几十款款黑客工具。涉及范围主要集中在 信息收集、Android黑客工具、自动化工具、网络钓鱼等,感兴趣的同学不容错过。

还有我视频里讲的案例源码和对应的工具包,需要的话也可以拿走。

因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取
如果你对网络安全入门感兴趣,那么你需要的话可以点击这里👉网络安全重磅福利:入门&进阶全套282G学习资源包免费分享!

最后就是我这几年整理的网安方面的面试题,如果你是要找网安方面的工作,它们绝对能帮你大忙。

这些题目都是大家在面试深信服、奇安信、腾讯或者其它大厂面试时经常遇到的,如果大家有好的题目或者好的见解欢迎分享。

参考解析:深信服官网、奇安信官网、Freebuf、csdn等

内容特点:条理清晰,含图像化表示更加易懂。

内容概要:包括 内网、操作系统、协议、渗透测试、安服、漏洞、注入、XSS、CSRF、SSRF、文件上传、文件下载、文件包含、XXE、逻辑漏洞、工具、SQLmap、NMAP、BP、MSF…

img

因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

如果你对网络安全入门感兴趣,那么你需要的话可以点击这里👉网络安全重磅福利:入门&进阶全套282G学习资源包免费分享!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值