黑马程序员——Java高新技术——反射(续)、成员方法的反射、数组的反射、Hashcode方法分析、类加载器等

----------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------------

                            反射(续)

一、Method

     1、l Method类代表某个类中的一个成员方法

     2、l得到类中的一个方法:

       例如:Method charAt=Class.forName(java.lang.String).getMethod(charAt,int.class);

     3、l调用方法

        通常方式:System.out.prinltn(str.charAt(1));

        反射方式:System.out.println(charAt.invoke(str,1));

        如果传递给Method对象的invoke()方法的第一个参数为null.这有着什么样的意义呢?

        说明该Method对象对应的是一个静态方法!

     4、lJdk1.4 和 jdk1.5invoke方法的区别:

     Jdk1.5:   public Object  invoke(Object  obj,Object.....args)

     JDK1.4:  public Object  invoke(Object obj,Object[] args)

jdk1.5的语法,整个数组是一个参数,而按jdk1.4的语法,数组中的每个元素对应一个参数,当把一个字符串数组作为参数传递给invoke方法时,javac会到底按照哪种语法进行处理呢?jdk1.5肯定要兼容jdk1.4的语法,会按jdk1.4的语法进行处理,即把数组打散成为若干个单独的参数。

5、专家模式:谁拥有数据,谁就是操作数据的专家。

   代码

     String str1=abc”我们的目的是 str1.charAt(1);

Method methodChatAt=String.class.getMethod(charAt,int.class);

System.out.println(methodCharAt.invoke(str1,1));

//这就是用反射的方法,拿到一份字节码中的方法,并让该方法起作用于某个对象。

Invoke()是所取到方法对象中的方法。

例子:圆对象去画圆

  Circle.draw();

面向对象:变量属性在谁身上,方法就在谁身上,这就是专家模式.

 

6、 对接收数组参数的成员方法进行反射 

      1)用反射方式执行某个类中的main方法

      目标

     写一个程序,这个程序能够根据用户提供的类名,去执行该类中的main方法

l   问题

    启动java程序的main方法的参数是一个字符串数组,即public static void main(String []args),通过反射方式来调用这个main方法时,如何为invoke方法传递参数呢?

 按jdk1.5的语法,整个数组是一个参数,而按jdk1.4的语法,数组中的每一个元素对应一个参数,当把一个字符串数组作为参数传递给invoke方法时,javac到底会按照哪种语法进行处理呢?

  Jdk1.5肯定要兼容jdk1.4的语法,会按jdk1.4的语法进行处理,即把数组打散成为若干个单独的参数。

所以,在给main方法传递参数时,不能使用代码mainMethod.invoke(null,new String[]{xxx}),javac只把它当作jdk1.4的语法进行理解,而不把它当作jdk1.5的语法解释,因此会出现参数类型不对的问题。

l 解决方法

   mainMethod.invoke(null,new Object[]{new String[]{xxx}});

   mainMethod.invoke(null,(Object)new String[]{xxx});,编译器会作特殊处理,编译时不把参数当作数组看待,也就不会数组打散成若干个参数了。

示例:

 

用反射方式执行Test类中的main方法

 

编译时,Run As——>RunConfigurations——>Arguments——>Program arguments中添加要执行的类名

二、数组的反射

     l1、具有相同维数和元素类型的数组属于同一个类型,即具有相同的Class实例对象。

       2、代表数组的Class实例对象的getSuperClass()方法返回的父类为Object类对应的Class

       3、l基本类型的一维数组可以被当作Object类型使用,不能当作Object[]类型使用,非基本类型的一维数组,既可以当作Object类型使用,又可以当作Object[]类型使用。

       4、lArrays.asList()方法处理int[]String[]时的差异。

          Array工具类用于完成对数组的反射操作

      51.4版本和1.5版本区别

      asList(Object[]a)它接收的是一个Object[],int是不能赋值给Object的,所以就用1.5版本处理

        1.5版本

      asList(T.....a)它等效接收的是一个Object对象,把一个int[]赋值给Object对象,返回的就是地址

       6、演示

   

 

三、ArrayListHashSet的比较及Hashcode分析

     1ArrayListHashSet的比较

     ArrayList 是一种有序的集合,它存放的对象的引用。如果同一个对象放进去两次,它也接收。因为相当于多一个引用变量,即便引用的是同一个对象,也没有关系。甚至可以插队,不是比较顺序,而是指先后顺序。

     而HashSet,存放对象时,它先判断里面有没有这个对象,如果有,就放不进去,不是覆盖。

如果想要覆盖,必须,把原来的给删除掉,然后把现在的写进去。

     2Hashcode方法的作用

如果一个集合中有很多元素,比如有一万个,并没有包含要查找的对象时,则意味着你的程序需要从该集合中取出一万个元素进行逐一比较才得到结论。有人发明了一种哈希算法来提高从集合中查找元素的效率。这种方式将集合分成若干个存储区域,每个对象可以计算出一个哈希码,可以将哈希码分组,每组分别对应某个存储区域,根据一个对象的哈希码就可以确定对象存储在哪一个区域。

   HashSet就是采用哈希算法存取对象的集合,它内部采用对某个数组n进行取余的方式对哈希码进行分组和划分对象的存储区域,object定义了一个hashcode方法来返回每个java对象的哈希码。

hashset集合中查找某个对象时,java系统首先调用对象的hashcode方法获取该对象的哈希码,然后根据哈希码找到相应区域,最后取出该存储区域中的每个元素与该对象进行equals方法比较,这样不用遍历集合中的所有元素就可以得到结论。可见hashset集合具有很好的对象检索功能。

提示:

1)如果两个对象的equals比较相等的话,也要让他们的hashcode也相等,但反之则不成立。即equals方法比较结果不想等的对象可以拥有相同的哈希码,或者说哈希码相同的两个对象equals方法比较的结果可以不等,

2)当一个对象被存储进hashset集合中后,就不能修改这个对象中的那些参与计算哈希值的字段了,否则,对象修改后的哈希值与最初存储进hashset集合中时的哈希值就不同了,在这种情况下,即使在contains方法使用该对象的当前引用作为参数去hashset集合中检索对象,也将返回找不到对象的结果,这也会导致无法从hashset集合中单独删除当前对象,从而造成内存泄露。

3、演示

 

 

                

四、反射的作用——>实现框架的功能

     我们使用类有两种方式,一种是使用别人的类,一种是别人使用我们的类

     框架:通过反射调用Java类的一种方式。

  l1、框架与框架要解决的核心问题

       我要做房子卖给用户住,由用户自己安装门窗和空调,我做的房子就是框架,用户需要使用我的框架,把门窗插入进我提供的框架中,框架与工具类有区别,工具类被用户的类调用,而框架则是调用用户提供的类。

2、框架要解决的核心问题

      因为在写程序时无法知道要被调用的类名,所以,在程序中无法直接new某个类的实例对象了,而要用反射方式类做。

   3、 简单框架程序的步骤:

        1)右击项目File命名一个配置文件如:config.properties,然后写入配置信息。如键值对:className=java.util.ArrayList,等号右边的配置键,右边是值。

        2)代码实现,加载此文件:

              (1)将文件读取到读取流中,要写出配置文件的绝对路径。

                    如:InputStream is=new FileInputStream(“配置文件”);

              (2)用Properties类的load()方法将流中的数据存入集合。

              (3)关闭流:关闭的是读取流,因为流中的数据已经加载进内存。

        3)通过getProperty()方法获取className,即配置的值,也就是某个类名。

        4)用反射的方式,创建对象newInstance()

        5)执行程序主体功能

 九、类加载器

1、类加载器是将.class的文件加载进内存,也可将普通文件中的信息加载进内存。

2、 文件的加载问题:

        1eclipse会将源程序中的所有.java文件编译成.class文件,然后放到classPath指定的目录中去。并且会将非.java文件原封不动的复制到.class指定的目录中去。在运行的时候,执行的是.class文件。

        2)将配置文件放到.class文件目录中一同打包,类加载器就会一同加载。

3、资源文件的加载:是使用类加载器。

        1)由类加载器ClassLoader来加载进内存,即用getClassLoader()方法获取类加载器,然后用类加载器的getResourceAsStream(String name)方法,将配置文件(资源文件)加载进内存。利用类加载器来加载配置文件,需把配置文件放置的包名一起写上。这种方式只有读取功能。

       2Class类也提供getResourceAsStream方法来加载资源文件,其实它内部就是调用了ClassLoader的方法。这时,配置文件是相对类文件的当前目录的,也就是说用这种方法,配置文件前面可以省略包名。

       如:类名.class.getResourceAsStream(“资源文件名”)

4、配置文件的路径问题:

        1)用绝对路径,通过getRealPath()方法运算出来具体的目录,而不是内部编码出来的。

        一般先得到用户自定义的总目录,在加上自己内部的路径。可以通过getRealPath()方法获取文件路径。对配置文件修改是需要要储存到配置文件中,那么就要得到它的绝对路径才行,因此,配置文件要放到程序的内部。

        2name的路径问题:

           (1)如果配置文件和classPath目录没关系,就必须写上绝对路径,

           (2)如果配置文件和classPath目录有关系,即在classPath目录中或在其子目录中(一般是资源文件夹resource),那么就得写相对路径,因为它自己了解自己属于哪个包,是相对于当前包而言的。

5、演示

 


---------- Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------------
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像中所有感兴趣的目标(物体),并确定它们的类别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像中目标的位置并识别出目标的类别。由于各类物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分类问题:判断图像中的目标属于哪个类别。 定位问题:确定目标在图像中的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分类 基于深度学习的目标检测算法主要分为两大类: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分类。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络中提取特征来预测物体分类和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 四、算法原理 以YOLO系列为例,YOLO将目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和类别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值