4.7 反射

news2024/11/22 21:52:34

文章目录

  • 1.概述
  • 2.为什么需要反射
  • 3.反射需要用到的API
    • 3.1 获取字节码对象
    • 3.2 常用方法
  • 4.反射的应用
    • 4.1 创建 : 测试物料类
    • 4.2 练习 : 获取类对象
    • 4.3 练习 : 类获取构造方法
    • 4.4 练习 : 获取成员方法
    • 4.5 练习:获取成员变量
    • 4.6 练习 : 创建对象
    • 4.7 熟悉API
      • 4.7.1 创建物科类
      • 4.7.2 物科类测试
  • 5.暴力反射
    • 5.1 创建 : 测试物料类
    • 5.2 练习 : 创建测试类


1.概述

首先我们要明白什么是反射;

通常,我们将拥有能够分析类的能力的程序称为反射;

Reflection(反射) 是 Java 程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查,或者说“自审”,也有称作“自省”。

反射非常强大,它甚至能直接操作程序的私有属性。我们前面学习都有一个概念,被private封装的资源只能类内部访问,外部是不行的,但这个规定被反射赤裸裸的打破了。

反射就像一面镜子,它可以在运行时获取一个类的所有信息,可以获取到任何定义的信息(包括成员变量,成员方法,构造器等),并且可以操纵类的字段、方法、构造器等部分。

但同时它也十分复杂,一般的应用程序员(指开发应用程序的程序员)并不需要考虑反射机制,主要是开发工具的程序员会比较多的使用它;

2.为什么需要反射

在刚接触反射时,对于它存在的意义会比较难理解,首先普通的信息,我们可以通过创建对象等方式来进行调用,不需要反射的参与;其次,私有的属性与信息是比较重要,不暴露在外的,但是现在又存在反射,是不是自相矛盾呢?

其实不是的,反射在很多时候可以帮助我们获取相关信息,这有时候会比创建对象更容易;私有的信息虽然不暴露在外,但是你的同事,甚至于你自己有时候还是需要使用到这些内容,反射也会提供比较安全的获取信息的方式,这样会让你的信息不会变的不安全,同时有限制的去使用相关内容;

3.反射需要用到的API

3.1 获取字节码对象

Class.forName(“类的全路径”);
类名.class
对象.getClass();

3.2 常用方法

获取包名 类名

clazz.getPackage().getName()//包名
clazz.getSimpleName()//类名
clazz.getName()//完整类名

获取成员变量定义信息

getFields()//获取所有公开的成员变量,包括继承变量
getDeclaredFields()//获取本类定义的成员变量,包括私有,但不包括继承的变量
getField(变量名)
getDeclaredField(变量名)

获取构造方法定义信息

getConstructor(参数类型列表)//获取公开的构造方法
getConstructors()//获取所有的公开的构造方法
getDeclaredConstructors()//获取所有的构造方法,包括私有
getDeclaredConstructor(int.class,String.class)

获取方法定义信息

getMethods()//获取所有可见的方法,包括继承的方法
getMethod(方法名,参数类型列表)
getDeclaredMethods()//获取本类定义的的方法,包括私有,不包括继承的方法
getDeclaredMethod(方法名,int.class,String.class)

反射新建实例

clazz.newInstance();//执行无参构造创建对象
clazz.newInstance(666,”海绵宝宝”);//执行含参构造创建对象
clazz.getConstructor(int.class,String.class)//获取构造方法

反射调用成员变量

clazz.getDeclaredField(变量名);//获取变量
clazz.setAccessible(true);//使私有成员允许访问
f.set(实例,值);//为指定实例的变量赋值,静态变量,第一参数给null
f.get(实例);//访问指定实例变量的值,静态变量,第一参数给null

反射调用成员方法

Method m = Clazz.getDeclaredMethod(方法名,参数类型列表);
m.setAccessible(true);//使私有方法允许被调用
m.invoke(实例,参数数据);//让指定实例来执行该方法

4.反射的应用

4.1 创建 : 测试物料类

package partFour;
/*本类用作测试反射的物科类,假装这是别人写的代码
 * 反射的前提:获取字节码对象,因为字节码对象中有这个类所有的关键信息*/
public class Student {
    //1.定义本类的成员变量
    private String name;
    int age;
    //2.给私有属性name提供get与set方法
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    //3.添加本类的无参与全参构造
    public Student(){ }
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    //4.添加普通方法
    public void eat(int n){
        System.out.println("今天要吃"+n+"碗大米饭?");
    }
}

4.2 练习 : 获取类对象

package partFour;

import org.junit.Test;

/**本类用来测试反射*/
public class TestReflect {
    //1.创建入口函数main()--不用
    /**单元测试方法:是java测试的最小单位,使用灵活,推荐使用
     * 语法要求: @Test + void + 没有参数 + public
     * 注意使用时需要导包:Add JUnit 4 library to the build path:import org.junit.Test;
     * 单元测试方法执行方式:选中方法名-->右键运行(Run As-->JUnit Test)-->出现小绿条说明执行成功
     */
    //2.通过单元测试来测试如何获取类对象
    @Test
    public void getClazz() throws Exception {
        /**右键要获取字节码对象的类名,选择Copy Quailfied Name复制类的全路径名*/
        Class<?> student1 = Class.forName("partFour.Student");//此处的参数是类的全路径名[包名+类名]
        Class<?> student2 = Student.class;
        Class<?> student3 = new Student().getClass();//先创建匿名对象,匿名对象没有名字,然后对象的字节码对象
        System.out.println(student1);//反射得到的字节码Class对象
        System.out.println(student2.getName());//获取类的全路径名[包名+类名]
        System.out.println(student3.getSimpleName());//只获取类名
        System.out.println(student3.getPackage().getName());//获取包名
    }
}

4.3 练习 : 类获取构造方法

package partFour;

import org.junit.Test;

import java.lang.reflect.Constructor;
import java.util.Arrays;

/*本类用于反射的测试*/
public class TestReflect2 {
    //通过单元测试方法获取Student类中的构造方法
    @Test
    public void getFunction() throws ClassNotFoundException {
        //1.获取字节码对象
        Class<?> Clazz = Class.forName("partFour.Student");//三种方式选择一种,注意forname需要抛出异常
        //2.通过字节码对象,获取目标类的成员方法
        Constructor<?>[] cs = Clazz.getConstructors();
        //3.查看每个方法信息
        //System.out.println(cs);//[Ljava.lang.reflect.Method;@1b9e1916
        System.out.println(Arrays.toString(cs));//已经获取到了方法,但是想遍历
        //4.把拿到的方法对象数组进行遍历
        for(Constructor c : cs){
            //通过每轮循环遍历到的方法对象,获取方法的各种信息
            System.out.println(c.getName());
            Class<?>[] types = c.getParameterTypes();
            System.out.println(Arrays.toString(types));
            //获取Student中的方法信息及其默认父类Object的方法信息
        }
    }
}


4.4 练习 : 获取成员方法

package partFour;

import org.junit.Test;

import java.lang.reflect.Method;
import java.util.Arrays;

/**本类用来测试反射*/
public class TestReflect3 {
    //通过单元测试来测试获取成员方法
    @Test
    public void getFunction() throws Exception {
        //1.获取Class字节码对象
        Class<?> clazz = Class.forName("partFour.Student");

        //2.获取所有成员方法
        Method[] ms = clazz.getMethods();

        //3.遍历数组,获取每个方法的信息
        for (Method m : ms) {
            System.out.println(m.getName());//获取方法名
            Class<?>[] pt = m.getParameterTypes();//获取方法参数类型
            System.out.println(Arrays.toString(pt));
        }
    }
}

4.5 练习:获取成员变量

package partFour;

import org.junit.Test;

import java.lang.reflect.Field;

public class TestReflect4 {
    //通过单元测试来测试获取成员变量
    @Test
    public void getFields(){
        //1.获取Class字节码对象
        /** Class<?>中的"?"是泛型约束的通配符,类似于"*" */
        Class<?> clazz = Student.class;

        //2.获取所有的成员变量,公共的!!!
        /**!!!注意目前成员变量的修饰符必须是public才能获取到,采用默认修饰符就反射不到*/
        Field[] fs = clazz.getFields();

        //3.遍历数组,获取每个成员变量的信息
        for (Field f: fs) {
            System.out.println(f.getName());//获取变量名
            System.out.println(f.getType().getName());//获取变量类型
        }
    }
}

4.6 练习 : 创建对象

package partFour;

import org.junit.Test;

import java.lang.reflect.Constructor;

public class TestReflect5 {
    /*本方法用于练习通过反射创建指定类Student的对象*/
    /*方式一:通过字节码对象之间调用newInstance(),触发目标类的无参构造来创建对象
     * 方式二:先获取指定参数类型的构造函数对象
     *       再通过获取到的这个构造函数对象调用newInsatnce(参数列表)
     *       来创建Student类对象*/
    @Test
    public void getObject() throws Exception {
        //1.获取字节码对象
        Class<?> clazz = Student.class;
        //2.通过反射创建对象
        Object o = clazz.newInstance();//这样已经创建对象了
        System.out.println(o);
        /*以上我们newInstance()触发的是Student类中的无参构造创建对象
         * 所以仅仅能创建对象,但不能给对象的属性赋值
         * 所以,如果需要触发其他的构造函数来创建对象的话
         * 需要先获取指定的构造函数对象*/
        //3.想尝试通过其他的构造函数来创建对象
        //3.1想用其他构造,先得获取,怎么获取?指定参数列表来获取
        /*本方法用于获取指定参数列表的构造函数,获取的是一个构造函数对象
         * 注意,这个方法的参数是目标类Student中对应构造函数的参数类型
         * 而且参入的是字节码对象,不是普通的类型*/
        Constructor<?> c = clazz.getConstructor(String.class,int.class);
        //3.2通过刚刚获取到的构造函数对象来帮我们创建Student类的对象
        Object o2 = c.newInstance("海绵宝宝", 18);
        /*向下转型:之前转成父类类型的子类对象
         * 如果想要使用子类的特有功能,需要重新转回成子类类型
         * 因为父类对象无法使用子类的特有功能*/
        //4.将多态对象转回子类对象--向下转型
        Student s = (Student) o2;
        System.out.println(s.getName());
        System.out.println(s.age);
        s.eat(999);
    }
}

4.7 熟悉API

自己创建类练习,获取类中的所有资源,熟悉反射中涉及的API

4.7.1 创建物科类

package partFour;
/* 本类用于复习反射的物科类*/
public class StudentEnd {
    //1.定义成员变量
    private String name;
    public int age;

    //2.


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    //3.生成本类的无参构造和全参构造
    public StudentEnd(){}
    public StudentEnd(String name,int age){
        this.name=name;
        this.age=age;
    }
    //4.提供本类的普通方法/成员方法
    public void play(){//无参的普通方法
        System.out.println("今天大结局");
    }
    public void sunDay(int n){
        System.out.println("国庆一共放"+n+"天");
    }
    //5.为了查看学生对象的具体属性和属性值,重写toString()
    @Override
    public String toString() {
        return "StudentEnd{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

4.7.2 物科类测试

package partFour;

import org.junit.Test;

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

/*本类用于反射的测试类*/
public class TestReflectionEnd {
    //单元测试方法:public + void + 没有参数 + @Test

    //1.通过单元测试方法,获取目标类Student对应的字节码对象
    @Test
    public void getClazz() throws ClassNotFoundException {
        //练习获取字节码对象的3中方式
        Class<?> clazz1 = Class.forName("partFour.StudentEnd");
        Class<?> clazz2 = StudentEnd.class;
        Class<?> clazz3 = new StudentEnd().getClass();

        System.out.println(clazz1);
        //class cn.review.Student  Student类对应的字节码对象
        System.out.println(clazz1.getName());
        //cn.review.Student 通过字节码对象获取到的Student的全路径名:包名+类名
        System.out.println(clazz1.getSimpleName());
        //Student 通过字节码对象获取到的Student的类名
        System.out.println(clazz2.getPackage());
        //package cn.review 通过字节码对象获取到的Student的包对象
        System.out.println(clazz2.getPackage().getName());
        //cn.review 通过包对象获取到的包名
    }
    //2.通过单元测试方法练习引用类型数组的定义与遍历
    @Test
    public void getStu(){
        //1.创建Student类的三个对象
        StudentEnd s1 = new StudentEnd("张三",3);
        StudentEnd s2 = new StudentEnd("李四",4);
        StudentEnd s3 = new StudentEnd("王麻子", 5);

        //2.创建数组将刚刚的3个对象存入数组中
        StudentEnd[] s = {s1,s2,s3};
        //3.直接打印数组,查看数组中的元素
        System.out.println(Arrays.toString(s));
        //4.遍历学生数组,拿到每一个学生对象,做进一步操作
        for(StudentEnd stu:s){
            System.out.println(stu);
            stu.play();//通过遍历到的对象执行play方法
            System.out.println(stu.age);//通过遍历到的对象,打印age属性
        }
    }
    //3.通过单元测试方法,获取Student类中的成员方法
    @Test
    public void getFunction() {
        //1.获取字节码对象
        Class<?> clazz = Student.class;

        //2.通过字节码对象,获取目标类中的成员方法们
        Method[] ms = clazz.getMethods();

        //3.通过高效for循环,拿到每一个方法对象
        for (Method m : ms) {
            System.out.println(m);//直接打印遍历到的方法对象
            System.out.println(m.getName());//通过方法对象获取方法名
            Class<?>[] pt = m.getParameterTypes();//通过方法对象获取方法所有参数的数组
            System.out.println(Arrays.toString(pt));//打印方法参数的数组
        }
    }

    //4.通过单元测试方法,获取Student类中的构造方法
    @Test
    public void getCons(){
        //1.获取字节码对象
        Class<?> clazz = new StudentEnd().getClass();
        //2.通过字节码对象获取目标类Student的构造方法们
        Constructor<?>[] cs = clazz.getConstructors();
        //3.通过高效for循环遍历数组
        for(Constructor c: cs){
            System.out.println(c.getParameterTypes());//打印本轮遍历到的构造方法的名字
            Class[] pt = c.getParameterTypes();//通过本轮遍历到的构造函数对象获取构造函数的参数类型
            System.out.println(Arrays.toString(pt));
        }
    }
    //5.通过单元测试方法,获取Student类中的成员变量
    @Test
    public void getFie() throws ClassNotFoundException{
        //1.获取字节码对象
        Class<?> clazz = Class.forName("partFour.StudentEnd");
        //2.通过字节码对象获取成员变量们
        Field[] fs = clazz.getFields();
        //3.遍历数组,获取每个成员变量的具体信息
        /*注意:目前成员变量的修饰符必须是public的才能获取到,默认修饰符也是获取不到的*/
        for(Field f : fs){
            System.out.println(f.getName());//通过本轮循环到的字段对象获取字段名
            System.out.println(f.getType());//通过本轮循环到的字段对象获取字段的类型
        }
    }
    //6.通过单元测试方法,创建Student目标类的对象
    @Test
    public void getObject() throws Exception {
        //1.获取字节码对象
        Class<?> clazz = StudentEnd.class;
        //2.通过反射技术,创建目标类的对象
        /*反射创建对象方案1:通过触发目标类的无参构造创建对象*/
        Object o = clazz.newInstance();//会抛出异常,需要throws
        System.out.println(o);//这一步已经获取大了对象Student{name='null', age=0}

        /*反射创建对象方案2:通过触发全参构造创建对象
         * 思路:1.先获取指定的构造函数对象,需要指定构造函数的参数,传入的是.class字节码对象
         *      2.通过刚刚获取到的获取到的构造函数对象,创建Student目标类的对象,并且给对象的属性赋值*/
        Constructor<?> c = clazz.getConstructor(String.class,int.class);
        //System.out.println(c);//public cn.review.Student(java.lang.String,int)
        Object o2 = c.newInstance("赵六", 6);
        System.out.println(o2);//Student{name='赵六', age=6}
    }
}

5.暴力反射

指可以将程序中的私有的属性或者方法通过反射技术,暴力的获取到资源。需要使用的常见方法如下:
在这里插入图片描述

5.1 创建 : 测试物料类

package partFour;
/*本类用作暴力反射测试物料类*/
public class Person {
    //1.提供私有属性
    private String name;
    private int age;
    //2.提供私有方法
    private void save(int n,String s){
        System.out.println("save()..."+n+s);
    }
    private void update(){
        System.out.println("update()...");
    }
}

5.2 练习 : 创建测试类

package partFour;

import org.junit.Test;

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

/*本类用于练习暴力反射*/
public class TestViolentReflection {
    @Test
    public void getFields() throws Exception {
        //1.获取字节码对象
        Class<?> clazz = Person.class;
        //2.获取指定的私有属性,传入的是属性名,注意抛出异常
        clazz.getDeclaredField("name");
        //3.根据刚刚获取到的属性对象,查看属性的信息
        Field field = clazz.getDeclaredField("name");
        System.out.println(field);//private java.lang.String cn.review.Person.name
        // 直接打印获取到的字段对象
        System.out.println(field.getType().getName());//java.lang.String
        System.out.println(field.getType());//class java.lang.String

        //4.设置属性的值
        //4.1需要指定到底是哪个对象的name属性设置值,没有对象就创建对象
        Object obj = clazz.newInstance(); //触发无参构造利用反射创建对象

        //4.2暴力反射需要设置私有可见权限
        field.setAccessible(true);


        //4.3通过字段对象给刚刚创建好的对象obj设置属性值为海绵宝宝
        //field就是我们刚刚捕获的name属性
        //set(m,n)--m是给哪个对象的name属性设置值,n是设置的值是什么
        field.set(obj,"海绵宝宝");

        //4.4打印查看刚刚设置的属性值
        //field.get(m)--field代表的就是Person类的name属性,m是查看哪个对象的这个属性值
        System.out.println(field.get(obj));//海绵宝宝
    }
    @Test
    public void getFie3() throws Exception {
        //1.获取字节码对象
        Class<?> clazz = Person.class;
        //2.根据获取到的属性对象,查看相关信息,比如属性的类型
        Field f = clazz.getDeclaredField("age");
        //3.根据获取到的属性对象,查看相关信息,比如属性的类型
        System.out.println(f.getType().getName());//int
        //4.操作:设置属性的值:一共需要三个元素:给哪个对象【1】的哪个属性【2】设置一个什么值【3】
        //4.1需要先指定给哪个对象的这个age属性设置值
        Object obj = clazz.newInstance();
        //4.2在给属性设置值之前,需要设置权限私有可见,否则报错
        f.setAccessible(true);
        //4.3通过刚刚获取到的age属性对象,给obj对象设置值
        f.set(obj,17);
        //4.4打印查看刚刚的属性值是否设置成功
        System.out.println(f.get(obj));//17
    }
    //3.创建单元测试方法:通过暴力反射获取与执行Person类的私有方法
    @Test
    public void getFunction2() throws Exception {
        //1.获取字节码对象
        Class<?> clazz = Person.class;
        //2.可以通过字节码对象获取某一个指定的私有方法对象
        //如何确定要找哪一个方法?方法名+参数列表
        Method method = clazz.getDeclaredMethod("save", int.class, String.class);

        /*在执行私有的方法之前,需要设置私有可见的权限*/
        method.setAccessible(true);
        //3.在执行获取到的方法前,需要先指定给哪个对象做这个save()操作
        //3.1没有对象就创建对象
        Object obj = clazz.newInstance();
        //3.2通过刚刚获取到的方法对象method给指定的对象obj做操作,注意传参
        method.invoke(obj,666,"哈哈哈");

        System.out.println(method);//save()...666哈哈哈
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

定时任务框架xxl-job及quartz

本文主要介绍分布式定时任务框架xxl-job&#xff0c;本文首先会对xxl-job做一个基本的介绍&#xff0c;接着将xxl-job与quartz做一个比较&#xff0c;最后就是介绍xxl-job调度的详细过程。 xxl-job官方文档 xxl-job的介绍 xxl-job是一个开源的分布式定时任务框架&#xff0c;其…

若依前后端分离版集成nacos

根据公司要求&#xff0c;需要将项目集成到nacos中&#xff0c;当前项目是基于若依前后端分离版开发的&#xff0c;若依的版本为3.8.3&#xff0c;若依框架中整合的springBoot版本为2.5.14。Nacos核心提供两个功能&#xff1a;服务注册与发现&#xff0c;动态配置管理。 一、服…

【django项目开发】用户登录后缓存权限到redis中(十)

这里写目录标题一、权限的数据的特点二、首先settings.py文件中配置redis连接redis数据库一、权限的数据的特点 需要去数据库中频繁的读和写&#xff0c;为了项目提高运行效率&#xff0c;可以把用户的权限在每次登录的时候都缓存到redis中。这样的话&#xff0c;权限判断的中…

基于投票策略的室内家具检测:VoteNet、BRNet 最全总结

文章目录一、基本概述二、VoteNet三、BRNet四、最新研究成果一、基本概述 最近几年&#xff0c;基于点云的3D目标检测是自动驾驶场景研究的热点。但是&#xff0c;自动驾驶主要聚焦于室外场景。本文&#xff0c;我们主要介绍两篇文章&#xff08;VoteNet&#xff0c;BRNet&…

HTML第一章总结

<h1~h6>标题标签 <br />换行标签&#xff08;单&#xff09; <p>分段标签 <strong>加粗标签 <em>倾斜标签 <del>删除线标签 <ins>下划线标签 <div>独占一行的布局标签 <span>进行分割的布局标签 <img>图片标签&a…

Go-micro[windows]安装以及踩坑

一.首先安装protochttps://github.com/protocolbuffers/protobuf/releases进入网址&#xff0c;点击tag&#xff0c;然后选择v3版本进入之后找到随后下载安装然后将protoc解压缩到任意目录&#xff08;自己选&#xff09;再将protoc/bin的路径放置环境变量中二.获取protoc-gen-…

RK3568 UBOOT的问题解决案例

一、UBOOT下的波特率 原始的波特率为1500000,串口工具虽然可以设置任意波特率&#xff0c;但工作时不正常。 输入不了。本文描述如何修改成115200。 二、确认UBOOT的配置 ./build.sh uboot processing option: uboot Start building uboot TARGET_UBOOT_CONFIGrk3568## make …

【C++】二叉树之力扣经典题目1——详解二叉树的递归遍历,二叉树的层次遍历

如有错误&#xff0c;欢迎指正。 如有不理解的地方&#xff0c;可以私信问我。 文章目录题目1&#xff1a;根据二叉树创建字符串题目实例思路与解析代码实现题目2&#xff1a;二叉树的层序遍历题目思路与解析代码实现题目1&#xff1a;根据二叉树创建字符串 点击进入题目链接—…

C++——多态|虚函数|重写|虚表

文章目录1. 多态的概念1.1 概念2. 多态的定义及实现2.1多态的构成条件2.2 虚函数2.3虚函数的重写虚函数重写的三个例外&#xff1a;2.4 普通调用和多态调用&#xff1a;2.5 C11 override 和 final2.6 重载、虚函数的覆盖(重写)、隐藏(重定义)的对比3. 抽象类(有关纯虚函数)3.1 …

互联网新时代要到来了(一)什么是Web3.0?

什么是Web3.0? tips&#xff1a;内容来自百度百科、知乎、搜狐新闻、李留白公众号、CSDN「Meta.Qing」博客等网页 什么是Web3.0?1.什么是Web3.0&#xff08;概念介绍&#xff09;&#xff1f;2.Web3.0简单理解3.Web3.0的技术特点4.Web3.0项目1.什么是Web3.0&#xff08;概念…

greenDao的使用文档

介绍&#xff1a;greenDAO 是一款轻量级的 Android ORM 框架&#xff0c;将 Java 对象映射到 SQLite 数据库中&#xff0c;我们操作数据库的时候&#xff0c;不在需要编写复杂的 SQL语句&#xff0c; 在性能方面&#xff0c;greenDAO 针对 Android 进行了高度优化&#xff0c; …

Ubuntu 20中安装snaphu

Ubuntu 20中安装snaphu0 前言1 snaphu安装步骤1.1 在控制台用命令行安装1.2 在官网下载安装包0 前言 snaphu是一个解缠软件。基于欧空局的SNAP snaphu的官网&#xff1a;https://web.stanford.edu/group/radar/softwareandlinks/sw/snaphu/ 1 snaphu安装步骤 大致有两种 在…

微软支持的ChatGPT激增,但不要低估苹果和谷歌

微软和 OpenAI 可能在 AI 聊天机器人爆炸式增长的市场中具有先发优势&#xff0c;但不要排除其他一些可以访问大量 AI 训练数据的科技巨头&#xff0c;例如 Apple 和 Google。 通过其对 ChatGPT 开发商 OpenAI 的早期和持续支持&#xff0c;微软在AI 军备竞赛中目前处于领先地…

鲸探玩家狂收往期数藏,2023年数藏二级市场的紧箍咒可能松动了?

图片来源&#xff1a;由无界AI绘画工具生成2月初&#xff0c;数藏发行平台鲸探更新了用户服务协议&#xff0c;更新最受关注的点在于&#xff1a;首次转赠期限从180天调整为90天。此外&#xff0c;有媒体披露&#xff0c;鲸探客服回答用户提问称&#xff0c;非首次转赠也从720天…

ITSS认证分为几个级别,哪个级别最高

​一、什么是ITSS ITSS( 信息技术服务标准&#xff0c;简称ITSS)是国内第一套成体系和综合配套的信息技术服务标准库&#xff0c;全面规范了IT服务产品及其组成要素&#xff0c;用于指导实施标准化和可信赖的IT服务。 ITSS是在工业和信息化部、国家标准化管理委员会的联合指导下…

Python 之 NumPy 统计函数、数据类型和文件操作

文章目录一、统计函数1. 求平均值 mean()2. 中位数 np.median3. 标准差 ndarray.std4. 方差 ndarray.var()5. 最大值 ndarray.max()6. 最小值 ndarray.min()7. 求和 ndarray.sum()8. 加权平均值 numpy.average()二、数据类型1. 数据存储2. 定义结构化数据3. 结构化数据操作三、…

儿童及婴幼儿产品出口美国CPC和欧洲CE认证测试标准总结

消费者越来越关注他们选购的产品安全性和质量&#xff0c;尤其是儿童和婴幼儿产品。若产品不符合安全标准和法规要求&#xff0c;可能对婴儿、幼儿和儿童造成威胁。儿童和婴幼儿产品的制造商及零售商必须严格遵守当地市场法规&#xff0c;证明其产品的安全性和质量可以满足消费…

为什么重写equals还要重写hashcode方法

目录equals方法hashCode方法为什么要一起重写&#xff1f;总结面试如何回答重写 equals 时为什么一定要重写 hashCode&#xff1f;要想了解这个问题的根本原因&#xff0c;我们还得先从这两个方法开始说起。 以下是关于hashcode的一些规定&#xff1a; 两个对象相等&#xff0…

文心ERNIE 3.0 Tiny新升级!端侧压缩部署“小” “快” “灵”!

大家好&#xff0c;今天带来的是有关文心ERNIE 3.0 Tiny新升级内容的文章。 近年来&#xff0c;随着深度学习技术的迅速发展&#xff0c;大规模预训练范式通过一次又一次刷新各种评测基线证明了其卓越的学习与迁移能力。在这个过程中&#xff0c;研究者们发现通过不断地扩大模型…

第七章:Linux最小化搭建环境解说2

配置IP地址&#xff1a;我们先要到网卡配置文件夹里&#xff0c;路径是/etc/sysconfig/network-scripts/&#xff0c;有点长&#xff0c;不过没事&#xff0c;我们要学会习惯&#xff0c;这还是经常用的。然后就是用ls命令查看下面有什么&#xff0c;只有一个文件ifcfg-ens160&…