反射与注解

news2024/12/24 21:22:29

【今日】

     人生只有一次   不妨大胆一点

目录

一   反射 

 1.访问构造方法

1.Constructor的使用

2.反射一个类中的所有构造方法

3.用Constructor创建并返回实列对象 

2.访问成员变量

1Field的使用方法

 2.反射一个类中的所有成员变量

3.获取修改成员变量的值 

3.访问成员方法 

 1.Method类方法

2.反射一个类中所有的成员方法

3.用反射调用方法 


 今日说法:反射

     通过Java的反射机制,程序员可以更深入地控制程序的运行过程。例如,可在程序运行时对用户输入的信息进行验证,还可以逆向控制程序的执行过程。另外,Java还提供了Annotation注解功能,该功能建立在反射机制的基础上。

一   反射 

 通过Java反射机制,可以在程序中访问已经装载到JVM中的Java对象的描述,实现访问、检测和修改描述Java对象本身信息的功能。Java反射机制的功能十分强大,在java.lang.reflect包中提供了对该功能的支持。
众所周知,所有Java类均继承了Object类,在Object类中定义了一个getClass方法,该方法返回一个类型为Class的对象。例如下面的代码:

JTexFileld texFild = new JTexFileld();    //创建JTexFileld对象
Class textFiekdC = textFiled.getClass();  //获取Class对象

利用Class类的对象textFieldC,可以访问用来返回该对象的描述信息。可以访问的主要描述信息如下表:

在讲具体的反射之前,我们要对构造方法,成员变量,成员方法有一定了解,可以复习一下之前内容:http://t.csdn.cn/68acc

 1.访问构造方法

     在通过下列一组方法访问构造方法时,将返回Constructor类型的对象或数组。每个Constructor对象代表一个构造方法,利用Constructor对象可以操纵相应的构造方法:

▣getConstructors()                                   

▣getConstructor()

▣getDeclaredConstructors()

▣getDeclaredConstructor()

因此我们要先了解Constructor的使用,以及Constructor类中提供的常用的方法。

1.Constructor的使用

在Java中,java.lang.reflect.Constructor类是Java反射API中的一个类,用于表示类的构造函数。通过Constructor类,我们可以获取、操作和调用类的构造函数。

下面是一些使用Constructor类的示例:

1.获取构造函数:


// 获取指定类的所有公共构造函数
Constructor[] constructors = SomeClass.class.getConstructors();

// 获取指定类的所有构造函数(包括非公共构造函数)
Constructor[] constructors = SomeClass.class.getDeclaredConstructors();

// 获取单个指定的构造函数
Constructor constructor = SomeClass.class.getDeclaredConstructor(paramTypes);

2.创建对象实例:

// 创建无参构造函数的对象实例
SomeClass obj = constructor.newInstance();

// 创建带有参数的构造函数的对象实例
SomeClass obj = constructor.newInstance(arg1, arg2, ...);

3.设置可访问性:

// 设置构造函数为可访问(用于访问非公共构造函数)
constructor.setAccessible(true);

4.获取构造函数信息:

// 获取构造函数的修饰符(public, private, protected, 等)
int modifiers = constructor.getModifiers();

// 获取构造函数的参数类型
Class<?>[] parameterTypes = constructor.getParameterTypes();

通过Constructor类,我们可以动态地获取、创建和调用类的构造函数,这在某些情况下非常有用,例如需要在运行时根据不同的条件创建对象或者调用非公共构造函数。但是请注意,反射操作通常会带来一些性能上的开销,因此只有在必要时才应该使用。

Constructor类的常用方法

在此之前我们先回顾一下构造方法的基本常识:

2.反射一个类中的所有构造方法

【代码实列】

public class Example {
	int id;
	String name;
	double price;
	public Example() {//无参的构造方法
		super();
	}
	public Example(int id) {//一个参数的构造方法
		super();
		this.id = id;
	}
	private Example(int id, String name, double price) {//三个参数的私有构造方法
		super();
		this.id = id;
		this.name = name;
		this.price = price;
	}
	
	

}
/*
 *这里创建了一个Example类
 *
 */


import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;

public class Demo {
	public static void main(String[] args) {
		try {
			Class c = Class.forName("Example");//传入string类型参数”Example",要求jvm查找并加载指定的类,返回的是一个class对象的引用。
			Constructor cons[]=c.getConstructors();//获取权限为public的构造方法
			for(Constructor con:cons) {
				System.out.print(Modifier.toString(con.getModifiers())+" ");//获取修饰符的信息
				System.out.print(con.getName()+"(");//获得方法名
				Class paras[] = con.getParameterTypes();//参数的类型
				for(int i=0;i<paras.length;i++) {
					System.out.print(paras[i].getSimpleName()+" args ");//获得参数类型的简化名字
					if(i!=paras.length-1) {
						System.out.print(",");
					}
				}
				System.out.println("){}");
				
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

}

【运行结果】

注意:我们可以发现运行结果只输出了两种构造方法,这是为什么呢?

 从代码中我们可以看到有以下三种构造方法:

之所以输出了两种是因为第三种构造方法是private是私密的, 而我们用的方法是c.getConstructors();获取的是公开的构造方法,要想获得所有的构造方法要用到方法c.getDeclaredConstructors()。改完后便可以得到三种构造方法:

3.用Constructor创建并返回实列对象 

创建一个类的对象需要使用到方法newInstance(Object...initargs)方法,下面详细介绍一下该方法:

newInstance() 方法是 Java 反射 API 中 java.lang.reflect.Constructor 类的一个方法。它用于创建并返回类的实例对象。通过 newInstance() 方法,可以通过不知道类名的情况下,根据类的构造函数创建实例对象。

newInstance() 方法有以下几种重载形式:

  1. T newInstance():如果类有一个可访问的无参数构造函数,那么将使用该构造函数创建类的实例。如果没有可访问的无参数构造函数,则会抛出 InstantiationException 异常。
    Class<?> cls = MyClass.class;
    Object obj = cls.newInstance();

  2. T newInstance(Object... initargs):如果类有一个匹配的构造函数,即参数类型与提供的参数相匹配,那么将使用该构造函数创建类的实例。如果没有匹配的构造函数,则会抛出 InstantiationException 异常。
    Class<?> cls = MyClass.class;
    Constructor<?> constructor = cls.getDeclaredConstructor(String.class, int.class);
    Object obj = constructor.newInstance("example", 10);

    通过 newInstance() 方法,我们可以动态地创建对象实例,而不需要直接调用类的构造函数。这在某些情况下非常有用,例如需要在运行时根据用户输入的类名创建对象等。需要注意的是,使用 newInstance() 方法时,类必须具有可访问的构造函数,并且参数类型必须与提供的参数匹配,否则会抛出异常。

还是以上面的代码为例来创建实列对象:

【代码】


public class Example {
	int id;
	String name;
	double price;
	public Example() {//无参的构造方法
		super();
	}
	public Example(int id) {//一个参数的构造方法
		super();
		this.id = id;
	}
	private Example(int id, String name, double price) {//三个参数的私有构造方法
		super();
		this.id = id;
		this.name = name;
		this.price = price;
	}
	@Override
	public String toString() {
		return "Example [id=" + id + ", name=" + name + ", price=" + price + "]";
	}
	
	
	

}
//先创建了一个Example类



import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;

public class Demo {
	public static void main(String[] args) {
		try {
			Class c = Class.forName("Example");//传入string类型参数”Example",要求jvm查找并加载指定的类,返回的是一个class对象的引用。
			Constructor cons[]=c.getDeclaredConstructors();//获取权限为public的构造方法
			
			for(Constructor con:cons) {
				System.out.print(Modifier.toString(con.getModifiers())+" ");//获取修饰符的信息
				System.out.print(con.getName()+"(");//获得方法名
				Class paras[] = con.getParameterTypes();//参数的类型
				for(int i=0;i<paras.length;i++) {
					System.out.print(paras[i].getSimpleName()+" args ");
					if(i!=paras.length-1) {
						System.out.print(",");
					}
				}
				System.out.println("){}");
			}
			//创建实列对象
			System.out.println("无参的实列对象:");
			Constructor cs1 = c.getDeclaredConstructor();//无参数的构造方法
			Object obj = cs1.newInstance();
			System.out.println(obj.toString());
			
			System.out.println("一个参的实列对象:");
			Constructor cs2 = c.getDeclaredConstructor(int.class);//一个参数的构造方法
			obj = cs2.newInstance(1024);
			System.out.println(obj.toString());
			
			System.out.println("三个参的实列对象:");
			Constructor cs3 = c.getDeclaredConstructor(int.class,String.class,double.class);//三个参数的构造方法
			obj = cs3.newInstance(123,"牛马",3.14);
			System.out.println(obj.toString());
				

		} catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
			e.printStackTrace();
		}
	}

}

【运行结果】

 注意:我们可以发现创建三个参的实列对象时,出现了报错!

这是因为第三个构造方法是私密的这时我们就要用到前面Constructor中所提到的设置可访问性:

// 设置构造函数为可访问(用于访问非公共构造函数)
constructor.setAccessible(true);

添加位置如下:

运行结果:

2.访问成员变量

在通过下列一组方法访问成员变量时,将返回Field类型的对象或数组。每个 Field对象代表一个成员变量,利用Field对象可以操纵相应的成员变量:
😶‍🌫️getFields()
😶‍🌫️getField(String name)
😶‍🌫️getDeclaredFields()
😶‍🌫️getDeclaredField(String name)
如果是访问指定的成员变量,可以通过该成员变量的名称来访问。例如,访问一个名称为birthday的成员变量,访问方法如下:

object. getDeclaredField("birthday");

 

1Field的使用方法

在Java中,反射API提供了java.lang.reflect.Field类来操作和访问类的字段。下面是Field类的一些常用方法的使用示例 :

  1. 获取字段对象:
    // 获取指定类的公共字段
    Field[] fields = SomeClass.class.getFields();
    
    // 获取指定类的所有字段(包括非公共字段)
    Field[] fields = SomeClass.class.getDeclaredFields();
    
    // 获取单个指定字段
    Field field = SomeClass.class.getDeclaredField("fieldName");

    以上代码中,我们使用getFields()方法获取指定类的公共字段,使用getDeclaredFields()方法获取指定类的所有字段(包括私有字段),使用getDeclaredField("fieldName")方法获取指定类中名为"fieldName"的字段。

  2. 获取和设置字段值:
    Object obj = new SomeClass();
    field.set(obj, value); // 设置字段值
    Object fieldValue = field.get(obj); // 获取字段值
  3. 获取字段的信息:
    String fieldName = field.getName(); // 获取字段名字
    Class<?> fieldType = field.getType(); // 获取字段类型
    int modifiers = field.getModifiers(); // 获取字段修饰符

    可以使用field.getName()方法获取字段的名称,使用field.getType()方法获取字段的类型,使用field.getModifiers()方法获取字段的修饰符信息,比如publicprivate等。

    通过使用Field类,我们可以在运行时动态地操作和访问类的字段,这对于需要在运行时通过反射来操作字段的值、类型和访问修饰符的情况非常有用。请注意,在使用反射时要小心处理异常,同时需要注意反射操作可能带来的性能开销。

Field类的常用方法 

 2.反射一个类中的所有成员变量

【代码实列】


public class Example {
	public int id=-1;
	public String name="XXX";
	private double price=3.14;

}


//先创建一个Example类



import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;


public class Demo {
	public static void main(String[] args) {
		try {
			Class c = Class.forName("Example");
			//Field[] fs = c.getFields();//返回所有公有属性
			Field[] fs = c.getDeclaredFields();//返回所有属性
			for(Field f:fs) {
				System.out.print(Modifier.toString(f.getModifiers())+" ");
				//f.getModifiers()获得成员变量采用的修饰符的整数,采用Modifier.toString()方法解析成为String类型
				System.out.print(f.getType().getSimpleName()+" ");//获得成员变量类型
				System.out.print(f.getName());
				System.out.println();
				
			}
		} catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchFieldException e) {
			e.printStackTrace();
		}
	}
}

 【运行结果】

3.获取修改成员变量的值 

我们来获取对应成员变量的属性:

1.id

 2.name

3.price

 这里报错是因为price是私密的没有权限我们要设置权限:

运行结果:

修改成员变量的属性:

添加代码如下:


运行结果:

3.访问成员方法 

   获取成员方法我们要用到Menthod方法。在通过下列一组方法访问成员方法时,将返回Method类型的对象或数组。每个Method对象代表一个方法,利用Method对象可以操纵相应的方法:
getMethods()
getMethod(String name, Class<?>...parameterTypes)
getDeclaredMethods()
getDeclaredMethod(String name, Class<?>..parameterTypes)。
如果是访问指定的方法,需要根据该方法的名称和入口参数的类型来访问。

 

 1.Method类方法

在Java中,java.lang.reflect.Method类用于表示类的方法。通过Method类,我们可以获取、调用和操作类的方法。

以下是Method类的一些常用方法的使用示例:

  1. 获取方法对象:
    // 获取指定类的公共方法(包括从父类继承的方法)
    Method[] methods = SomeClass.class.getMethods();
    
    // 获取指定类的所有方法(包括非公共方法)
    Method[] methods = SomeClass.class.getDeclaredMethods();
    
    // 获取单个指定方法
    Method method = SomeClass.class.getDeclaredMethod("methodName", parameterTypes);
  2. 调用方法:
    Object obj = new SomeClass();
    method.invoke(obj, args);
  3. 获取方法的信息:
    String methodName = method.getName(); // 获取方法名字
    Class<?> returnType = method.getReturnType(); // 获取方法返回类型
    Class<?>[] parameterTypes = method.getParameterTypes(); // 获取方法参数类型数组
    int modifiers = method.getModifiers(); // 获取方法的修饰符

    使用getName()方法获取方法的名称,使用getReturnType()方法获取方法的返回类型,使用getParameterTypes()方法获取方法的参数类型数组,使用getModifiers()方法获取方法的修饰符信息,比如publicprivate等。

  4. 通过Method类,我们可以在运行时动态地获取和调用类的方法,这对于需要在运行时通过反射来操作方法的返回值、参数和修饰符的情况非常有用。需要注意,在使用反射时要小心处理异常,同时需要注意反射操作可能带来的性能开销。

2.反射一个类中所有的成员方法

代码如下:
 

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;


public class Demo {
	
	public static void main(String[] args) {
		try {
			Class c = Class.forName("java.lang.String");
			Method ms[] = c.getDeclaredMethods();
			for(Method m: ms) {
				System.out.print(Modifier.toString(m.getModifiers())+" ");//获取修饰符
				System.out.print(m.getReturnType().getSimpleName()+" ");//返回值
				System.out.print(m.getName()+"(");//方法名字
				Class para[] = m.getParameterTypes();
				for(int i = 0;i<para.length;i++ ) {
					System.out.print(para[i].getSimpleName()+" arg ");
					if(i!=para.length-1) {
						System.out.print(",");
					}
				}
				System.out.println(")");
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		
	}
}

【运行结果】

3.用反射调用方法 

【代码】

public class Example {
	public void add(int a,int b) {
		System.out.println("a+b="+(a+b));
	}

}


import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;


public class Demo {
	
	public static void main(String[] args) {
		try {
			Class c = Class.forName("Example");
			Method ms[] = c.getDeclaredMethods();
			for(Method m: ms) {
				System.out.print(Modifier.toString(m.getModifiers())+" ");//获取修饰符
				System.out.print(m.getReturnType().getSimpleName()+" ");//返回值
				System.out.print(m.getName()+"(");//方法名字
				Class para[] = m.getParameterTypes();
				for(int i = 0;i<para.length;i++ ) {
					System.out.print(para[i].getSimpleName()+" arg ");
					if(i!=para.length-1) {
						System.out.print(",");
					}
				}
				System.out.println(")");
			}
			Constructor cs = c.getConstructor();
			Object obj = cs.newInstance();
			Method m = c.getDeclaredMethod("add",int.class,int.class);
			m.invoke(obj,265,236);
		} catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
			e.printStackTrace();
		}
		
	}
}

【运行结果】

@over! 

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

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

相关文章

javaee springMVC model的使用

项目结构图 pom依赖 <?xml version"1.0" encoding"UTF-8"?><project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org…

【LeetCode75】第五十一题 最大子序列的分数

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 题目给我们两个长度一样的数组&#xff0c;让我们再num1中找出一个长度为k的子序列&#xff0c;然后把这个子序列累加的和乘上在nums2中对…

74 QML ProgressBar显示进度数字

1 引言 由于目前使用的是qt.5.14版本&#xff0c;Qt Quick Controls 已经从1.0版本 变为2.0版本了&#xff0c;如果继续使用的Qt Quick Controls 1 的style:方式&#xff0c;改变进度条的样式已经不行了&#xff0c;其会报错&#xff1a;Invalid property name "style&quo…

Langchain的一些问题和替代选择

Langchain因其简化大型语言模型(llm)的交互方面的到关注。凭借其高级的API可以简化将llm集成到各种应用程序中的过程。 但是Langchain乍一看似乎是一个方便的工具&#xff0c;但是它有时候否更像是一个语言迷宫&#xff0c;而不是一个直截了当的解决方案。在本文中&#xff0c…

mysql 增量备份与恢复使用详解

目录 一、前言 二、数据备份策略 2.1 全备 2.2 增量备份 2.3 差异备份 三、mysql 增量备份概述 3.1 增量备份实现原理 3.1.1 基于日志的增量备份 3.1.2 基于时间戳的增量备份 3.2 增量备份常用实现方式 3.2.1 基于mysqldump增量备份 3.2.2 基于第三方备份工具进行增…

安装 Gin 框架

首先需要在目录下初始化一下 go 项目 go init可以看到生成了一个go.mod文件&#xff0c;然后使用以下命令安装 gin 框架 go get -u github.com/gin-gonic/gin养成一个好习惯&#xff0c;在写项目之前先初始化项目 go mod init go mod tidy如果不初始化项目的话没有第三方库补…

Tampermonkey实践:安装引导及开发一个网页背景色更改插件

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;CSDN领军人物&#xff0c;全栈领域优质创作者✌&#xff0c;CSDN博客专家&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师…

基于SpringBoot的火车订票管理系统

基于SpringBootVue的火车订票管理系统&#xff0c;前后端分离 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBoot、Vue、Mybaits Plus、ELementUI工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 【主要功能】 角色&#xff1a;管理员、会员 会员&…

java_日期时间API

文章目录 一、JDK8之前的日期时间API1.1 System类的currentTimeMillis()1.2 两个Date类1.2.1 java.util.Date包下的1.2.2 java.sql.Date包下的 一、JDK8之前的日期时间API 1.1 System类的currentTimeMillis() 获取当前时间对应的毫秒数&#xff0c;long类型 当前时间与1970年1…

vscode各种配置的方法

一. vscode配置 vscode 是微软公司提供的一个 代码编辑器。是做C/C常用的编辑器。 在安装后&#xff0c;可以根据自己需要自行安装常用的配置插件。同时&#xff0c;也可以在设置栏设置自己需要的功能&#xff0c;以方便使用。 下面学习 vscode的几种常见的设置。 二. vsco…

vue中 字体图标引入 - iconfont阿里字体图标库

官网&#xff1a;iconfont-阿里巴巴矢量图标库 代码应用中&#xff0c;有许多方法&#xff0c;如何使用该图标库。如&#xff0c;icon单个使用、unicode引用、或 font-class引用&#xff08;推&#xff09;、symbol&#xff08;svg合集&#xff09;。本文主讲 font-class 方法…

C#,《小白学程序》第十六课:随机数(Random)第三,正态分布的随机数的计算方法与代码

1 随机数的问题 用 C# Random 类生成的随机数是平均分布的。也就是各数据段的出现的次数差不多。彩票号码属于这种随机数。 而很多很多常见的随机数&#xff0c;比如&#xff1a;成绩&#xff0c;却是符合正态分布的。 因而很多时候需要生成符合正态分布规律的随机数。 2 文…

JavaFx之Hello, World!

当使用 JavaFX 进行应用程序开发时&#xff0c;Application 类是一个关键组件。它是 JavaFX 应用程序的入口点&#xff0c;负责启动应用程序并设置应用程序的主舞台&#xff08;Stage&#xff09;和场景&#xff08;Scene&#xff09;。下面是一个详细介绍 Application 类并带有…

MySQL——锁

简介 多线程访问共享资源的时候&#xff0c;避免不了资源竞争而导致数据错乱的问题&#xff0c;所以我们通常为了解决这一问题&#xff0c;都会在访问共享资源之前加锁。 锁的分类 Mysql中的锁机制基本上都是采用的悲观锁来实现的。 行锁 行锁就是一锁锁一行或者多行记录&a…

【Spatial-Temporal Action Localization(一)】认识时空动作定位

文章目录 任务定义任务难点数据集任务现状评估指标可以思考的创新的角度 不错的博客&#xff0c;还有框架推荐 南京大学开源MultiSports&#xff1a;面向体育运动场景的细粒度多人时空动作检测数据集… 论文阅读推荐、Video Understanding&#xff08;3&#xff09;Spatio-Te…

d3dcompiler_47.dll缺失怎么修复,这个方法电脑小白也能学会

在计算机领域&#xff0c;d3dcompiler_47.dll文件是DirectX的一部分&#xff0c;用于执行硬件加速的图形渲染。当遇到“找不到d3dcompiler_47.dll丢失”的问题时&#xff0c;通常表示系统缺少此文件或其路径设置不正确。本文将介绍一些详细解决方法&#xff0c;帮助您解决这个问…

外观数列问题

给定一个正整数 n &#xff0c;输出外观数列的第 n 项。 「外观数列」是一个整数序列&#xff0c;从数字 1 开始&#xff0c;序列中的每一项都是对前一项的描述。 你可以将其视作是由递归公式定义的数字字符串序列&#xff1a; countAndSay(1) "1" countAndSay(n…

Docker的架构描述与安装部署

概述 Docker是一个开放的容器化平台&#xff0c;其提供能力轻松地支撑业务应用的开发、打包、装载、分发以及运行&#xff0c;在DevOps领域中&#xff0c;docker能高效地应对业务应用的持续集成以及持续发布&#xff08;CI/CD&#xff09;&#xff0c;其架构如下所示&#xff…

2023金九银十必看前端面试题!2w字精品!

文章目录 导文CSS1. 请解释CSS的盒模型是什么&#xff0c;并描述其组成部分。2. 解释CSS中的选择器及其优先级。3. 解释CSS中的浮动&#xff08;float&#xff09;是如何工作的&#xff0c;并提供一个示例。4. 解释CSS中的定位&#xff08;position&#xff09;属性及其不同的取…

机器人制作开源方案 | 桌面级机械臂--应用设计

本节内容将基于机器视觉带着大家进行应用实训。机器视觉是人工智能正在快速发展的一个分支&#xff0c;简单说来机器视觉就是用机器代替人眼来做测量和判断。机器视觉系统是通过机器视觉产品&#xff08;即图像摄取装置&#xff0c;分CMOS和CCD两种&#xff09;将被摄取目标转换…