Java反射机制的学习

2023-11-15

转自:http://www.cnblogs.com/keis/archive/2011/03/29/1998736.html


Java反射机制是Java语言被视为准动态语言的关键性质。Java反射机制的核心就是允许在运行时通过Java Reflection APIs来取得已知名字的class类的相关信息,动态地生成此类,并调用其方法或修改其域(甚至是本身声明为private的域或方法)。

也许你使用Java已经很长时间了,可是几乎不会用到Java反射机制。你会嗤之以鼻地告诉我,Java反射机制没啥用。或许在J2EEJ2SE等平台,Java反射机制没啥用(具体我也不了解,不多做评论),但是在Android应用开发中,该机制会带给你许多惊喜。

如果熟悉Android,那么你应该知道,Google不知出于什么原因,在系统源码中一些类或方法中经常加上“@hide”注释标记。它的作用是使这个方法或类在生成SDK时不可见,因此由此注释的东西,你在编译期是不可见的。这就出现了一些问题。一些明明可以访问的东西编译期却无法访问了!这使得你的程序有些本来可以完成的功能无法编译通过。

当然,有一种办法是自己去掉Android源码中的所有“@hide”标记,然后重新编译一份自己的SDK。另一种办法就是使用Java反射机制。当然,你还可以利用反射来访问存在访问限制的方法和修改其域。不过这种使用方法比较特殊,我们在文章的最后单独讨论。

从Class类说起

如果你使用Java,那么你应该知道Java中有一个Class类。Class类本身表示Java对象的类型,我们可以通过一个Object(子)对象的getClass方法取得一个对象的类型,此函数返回的就是一个Class类。当然,获得Class对象的方法有许多,但是没有一种方法是通过Class的构造函数来生成Class对象的。

也许你从来没有使用过Class类,也许你曾以为这是一个没什么用处的东西。不管你以前怎么认为,Class类是整个Java反射机制的源头。一切关于Java反射的故事,都从Class类开始。

因此,要想使用Java反射,我们首先得到Class类的对象。下表列出了几种得到Class类的方法,以供大家参考。

Class object 诞生管道

示例

运用getClass()

注:每个class 都有此函数

String str = "abc";

Class c1 = str.getClass();

运用

Class.getSuperclass()

Button b = new Button();

Class c1 = b.getClass();

Class c2 = c1.getSuperclass();

运用static method

Class.forName()

(最常被使用)

Class c1 = Class.forName ("java.lang.String");

Class c2 = Class.forName ("java.awt.Button");

Class c3 = Class.forName ("java.util.LinkedList$Entry");

Class c4 = Class.forName ("I");

Class c5 = Class.forName ("[I");

运用

.class 语法

Class c1 = String.class;

Class c2 = java.awt.Button.class;

Class c3 = Main.InnerClass.class;

Class c4 = int.class;

Class c5 = int[].class;

运用

primitive wrapper classes

的TYPE 语法

Class c1 = Boolean.TYPE;

Class c2 = Byte.TYPE;

Class c3 = Character.TYPE;

Class c4 = Short.TYPE;

Class c5 = Integer.TYPE;

Class c6 = Long.TYPE;

Class c7 = Float.TYPE;

Class c8 = Double.TYPE;

Class c9 = Void.TYPE;

获取一些基本信息

在我们得到一个类的Class类对象之后,Java反射机制就可以大施拳脚了。首先让我们来了解下如何获取关于某一个类的一些基本信息。

Java class 内部模块

Java class 内部模块说明

相应之Reflection API,多半为Class methods。

返回值类型(return type)

package

class隶属哪个package

getPackage()

Package

import

class导入哪些classes

无直接对应之API。可间接获取。

 

modifier

class(或methods, fields)的属性

int getModifiers()

Modifier.toString(int)

Modifier.isInterface(int)

int

String

bool

class name or interface name

class/interface

名称getName()

String

type parameters

参数化类型的名称

getTypeParameters()

TypeVariable <Class>[]

base class

base class(只可能一个)

getSuperClass()

Class

implemented interfaces

实现有哪些interfaces

getInterfaces()

Class[]

inner classes

内部classes

getDeclaredClasses()

Class[]

outer class

如果我们观察的class 本身是inner classes,那么相对它就会有个outer class。

getDeclaringClass()

Class

上表中,列出了一些Java class内部信息的获取方式。所采用的方法几乎都是调用Class对象的成员方法(由此你就可以了解到Class类的用处了吧)。当然,表中所列出的信息并不是全部,有很大一部分没有列出,你可以通过查阅Java文档得到更全面的了解。另外,下面将重点介绍一下类的构造函数、域和成员方法的获取方式。

类中最重要的三个信息

如果要对一个类的信息重要性进行排名的话,那么这三个信息理应获得前三的名次。它们分别是:构造函数、成员函数、成员变量。

也许你不同意我的排名,没关系。对于Java反射来说,这三个信息与之前介绍的基本信息相比较而言,有着本质的区别。那就是,之前的信息仅仅是只读的,而这三个信息可以在运行时被调用(构造函数和成员函数)或者被修改(成员变量)。所以,我想无可否认,至少站在Java反射机制的立场来说,这三者是最重要的信息。

下面,让我们分别了解一下这三个重要信息的获取方式。另外,我们将在后面的章节,详细介绍他们的调用方式或者修改方式。

构造函数

如果我们将Java对象视为一个二进制的生活在内存中生命体的话,那么构造函数无疑可以类比为Java对象生命体的诞生过程。我们在构造函数调用时为对象分配内存空间,初始化一些属性,于是一个新的生命诞生了。

Java是纯面向对象的语言,Java中几乎所有的一切都是类的对象,因此可想而知构造函数的重要性。

Java反射机制能够得到构造函数信息实在应该是一件令人惊喜的事情。正因为此,反射机制实质上才拥有了孵化生命的能力。换句话言之,我们可以通过反射机制,动态地创建新的对象。

获取构造函数的方法有以下几个:

Constructor getConstructor(Class[] params) 

Constructor[] getConstructors()

Constructor getDeclaredConstructor(Class[] params) 

Constructor[] getDeclaredConstructors()

我们有两种方式对这四个函数分组。

首先可以由构造函数的确定性进行分类。我们知道,一个类实际上可以拥有很多个构造函数。那么我们获取的构造函数是哪个呢?我们可以根据构造函数的参数标签对构造函数进行明确的区分,因此,如果我们在Java反射时指定构造函数的参数,那么我们就能确定地返回我们需要的那个“唯一”的构造函数。getConstructor(Class[] params) getDeclaredConstructor(Class[] params)正是这种确定唯一性的方式。但是,如果我们不清楚每个构造函数的参数表,或者我们出于某种目的需要获取所有的构造函数的信息,那么我们就不需要明确指定参数表,而这时返回的就应该是构造函数数组,因为构造函数很可能不止一个。getConstructors()getDeclaredConstructors()就是这种方式。

另外,我们还可以通过构造函数的访问权限进行分类。在设计类的时候,我们往往有一些构造函数需要声明为“private”、“protect”或者“default”,目的是为了不让外部的类调用此构造函数生成对象。于是,基于访问权限的不同,我们可以将构造函数分为public和非public两种。

getConstructor(Class[] params) getConstructors()仅仅可以获取到public的构造函数,而getDeclaredConstructor(Class[] params) getDeclaredConstructors()则能获取所有(包括public和非public)的构造函数。

成员函数

如果构造函数类比为对象的诞生过程的话,成员函数无疑可以类比为对象的生命行为过程。成员函数的调用执行才是绝大多数对象存在的证据和意义。Java反射机制允许获取成员函数(或者说成员方法)的信息,也就是说,反射机制能够帮助对象践行生命意义。通俗地说,Java反射能使对象完成其相应的功能。

和获取构造函数的方法类似,获取成员函数的方法有以下一些:

Method getMethod(String name, Class[] params)

Method[] getMethods()

Method getDeclaredMethod(String name, Class[] params) 

Method[] getDeclaredMethods() 

其中需要注意,String name参数,需要写入方法名。关于访问权限和确定性的问题,和构造函数基本一致。

成员变量

成员变量,我们经常叫做一个对象的域。从内存的角度来说,构造函数和成员函数都仅仅是Java对象的行为或过程,而成员变量则是真正构成对象本身的细胞和血肉。简单的说,就是成员变量占用的空间之和几乎就是对象占用的所有内存空间。

获取成员变量的方法与上面两种方法类似,具体如下:

Field getField(String name)

Field[] getFields()

Field getDeclaredField(String name)

Field[] getDeclaredFields()

其中,String name参数,需要写入变量名。关于访问权限和确定性的问题,与前面两例基本一致。

让动态真正动起来

在本文的一开始就说,Java反射机制是Java语言被视为准动态语言的关键性质。如果Java反射仅仅能够得到Java类(或对象)运行时的信息,而不能改变其行为和属性,那么它当然算不上“动态”。百度了一把何谓“动态语言”,解释如下:动态语言,是指程序在运行时可以改变其结构:新的函数可以被引进,已有的函数可以被删除等在结构上的变化。由此看来,Java确实不能算作“动态语言”。但是和CC++等纯静态语言相比,Java语言允许使用者在运行时加载、探知、使用编译期间完全未知的classes,所以我们说Java是“准动态”语言。

细心地读者可能已经发现,在“类中最重要的三个信息”一节中,我们获取的信息其实都是属于类的,而不是对象。对于类的信息提取,其实并不涉及到对象内存,在程序编译完成的那一刻起,一切都已经是确定的了。因此,它并不能算“动态”。而如何对对象内存进行操作和访问,才是“动”的真正含义。

说了这么多,关键还在于如何利用反射让Java真正动起来。下面我将按照创生、行为与属性三个方面来介绍反射机制是如何让Java动的。

创生

不知是否本性使然,人类偏爱于思索起源与终结的话题。如果将程序类比于一个二进制的世界的话,那么我们程序员则是这个世界的上帝。我们掌控着这个世界的起源和终结,熟悉世界中一草一木的属性和所有生灵的习性。现在就让我们开始创世纪吧!

在 “构造函数”那一小节中,我们列出了获取构造函数的四种方法。这四种方法的返回值不知是否引起了各位的注意,那就是Constructor类。Constructor就类比于女娲吹给泥人的那一口真气,有了它,一个生命才真正出现。

Constructor支持泛型,也就是它本身应该是Constructor<T>。这个类有一个public成员函数,newInstance(Object... args),其中args为对应的参数。我们正是通过它来实现创生的过程。

行为

行为践行着生命的意义,而众多事物的行为才得以构成整个世界的运转。尽管道家的老子主张“无为而治”,宣扬“圣人处无为之事,行不言之教”,但那是因为他本身就是 “无”的信仰者(“道”即“无”)。我们是唯物主义的信徒,所以必然要以“有”为价值。那么,在二进制的世界里,我们如何调用Java对象的行为呢?

同样,我们首先回顾“成员函数”小节中四种方法的返回值。对,那就是Method类。此类有一个public成员函数,Object invoke(Object receiver, Object... args)。我们能很好理解此函数的第二个参数args,它代表这个方法所需要接收的参数。也许大家对第一个参数receiver还存在疑惑之处。这得从编程语言的发展历程讲起。

如果你关注几种主流编程语言的起源,那么你能有这样的印象:C从汇编而来,C++C而来,而JavaC/C++而来。有这样一种印象就足够了。从这样的发展史我们可以看出,C++Java这两种面向对象的编程语言都是从面向过程的C语言基础上发展而来的。OOP是一种思想,它本身与编程语言无关。也就是说,我们用C也能写出面向对象的程序,这也是C++Java能够以C为基础的根本所在。然而,C无法实现类似object.method()这种表现形式,因为C语言的结构体中并不支持函数定义。那么我们用C实现OOP的时候,如何调用对象的方法呢?

本质上说,object.method()这种调用方式是为了表明具体method()的调用对象。而invoke(Object receiver, Object... args)的第一个参数正是指明调用对象。在C++中,object.method()其实是有隐含参数的,那就是object对象的指针,method原型的第一个参数其实是this指针,于是原型为method(void* this)

这样一溯源,也许你更清楚了Object receiver参数的含义,或许更迷糊了?不管怎样,历史就是如此,只不过我个人能力有限,说不清楚而已。

另外需要注意的是,如果某个方法是Java类的静态方法,那么Object receiver参数可以传入null,因为静态方法不从属于对象。

属性

同样是人类,令狐冲和岳不群是如何被区分开的?那是因为他们有着不同的属性。同样,同一个类可以生成多个对象,几个同类型的对象之间如何区分?属性起着决定性的作用。说到这里,想起一个科幻故事。人体瞬移机,作用的根本原理就是人进入A位置,被完全扫描之后,再在B位置重新组成它的细胞、血肉等属性,从而完全创造出另一个一模一样的人。当然,这是唯物主义的极致,它假设了只要一切物质相同,连记忆和灵魂都不会出现偏差,另外还存在伦理的问题,例如A位置的人会被销毁掉吗?

尽管这是一个科幻,但是在程序的世界里,我们早已经用上了这类似幻想的技术。Java中如何远程传递一个对象?我们已经使用上了Java对象序列化的接口。不仅如此,利用序列化接口,我们甚至可以将一个生命保存起来,在需要的时候将它复活,这就是对象的持久化。不得不感慨,在程序的世界里,我们就是上帝啊!

对象序列化如此强大,那么它的本质是什么呢?它的工作原理是怎样的呢?简单的说,对象序列化的本质就是属性的序列化。原理就是我们崇尚的唯物主义,如果同一个类的两个对象所有属性值都完全相同,那么我们可以认为这是同一个对象。

说了这么多,只是想说明一件事情,属性对于对象而言是多么的重要。那么如何读写对象中属性的值呢?回顾获取属性信息的方法返回值类型,那是FieldField类有两个public方法,分别对应读与写,它们是:

Object get(Object object)

void set(Object object, Object value)

object参数需要传入的对象,原理类似于成员方法需要指明对象一样。如果是静态属性,此值同样可以为null

关于反射的一些高级话题

如果说前面那些属于Java反射的基本知识,那么在文章的最后,我们来探讨一下反射的一些高级话题。另外,本文对基础知识的讲解仅属于抓主干,具体的一些旁支可以自己参看文档。需要提一下的是,Java反射中对数组做过单独的优化处理,具体可查看java.lang.reflect.Array类;还有关于泛型的支持,可查看java.lang.reflect.ParameterizedType及相关资料。

暂时想到的高级话题有三个,由于对Java反射理解的也不算深入,所以仅仅从思路上进行探讨,具体实现上,大家可以参考其他相关资料,做更深入研究。

Android编译期问题

Android的安全权限问题我把它简单的划分成三个层次,最不严格的一层就是仅仅骗过编译器的“@hide”标记。对于一款开源的操作系统而言,这个标记本身并不具备安全上的限制。不过,从上次Google过来的负责Android工程师的说法来看,这个标记的作用更多的是方便硬件厂商做闭源的二次开发。这样解释倒也说得过去。

不过这并不影响我们使用反射机制以绕过原生Android的第一层安全措施。如果你熟悉源码的话,会发现这可以应用到很多地方。并且最关键的是你并不需要放在源码中编译,而是像普通应用程序的开发过程一样。

具体使用范围我不能一一列举了,例如自定义窗口、安装程序等等。简单的说,在Android上使用反射技术,你才会对Android系统有更深的理解和更高的控制权。

软件的解耦合

我们在架构代码的时候,经常提到解耦合、弱耦合。其实,解耦和不仅仅只能在代码上做文章。我们可以考虑这样一种情况:软件的功能需求不可能一开始就完全确定,有一些功能在软件开发的后期甚至是软件已经发布出去之后才想到要加入或者去掉。

按我们惯有的思维,这种情况就得改动源码,重新编译。如果软件已经发布出去,那么就得让客户重新安装一次软件。反思一下,我们是否认为软件和程序是同一回事呢?事实上,如果你能将软件和程序分开来理解,那么你会发现,为了应对以上的情况,我们还有其他的解决办法。

我国有一个很重要但是很麻烦的制度,那就是户籍制度。它的本意是为了更好的管理人口事宜。每当一个孩子出生,我们就需要在户籍管理的地方去给他办理户籍入户;而每当一个人去世,我们也需要在相应的地方销去他的户籍。既然我们可以视类为生命,那么我们能否通过学习这样的户籍管理制度来动态地管理类呢?

事实上这样的管理是可行的,而且Java虚拟机本身正是基于这样的机制来运行程序的。因此我们是否可以这样来架构软件框架。首先,我们的软件有一个配置文件,配置文件其实是一个文本,里面详细描述了,我们的软件核心部分运行起来后还需要从什么路径加载些什么类需要何时调用什么方法等。这样当我们需要加或减某些功能时,我们只需要简单地修改配置文本文件,然后删除或者添加相应的.class文件就可以了。

如果你足够敏感,你或许会发现,这种方式形成的配置文件几乎可以相当于一门脚本语言了。而且这个脚本的解释器也是我们自己写的,另外关键是它是开发的,你可以为它动态地加入一些新的类以增加它的功能。

不要以为这仅仅是一个设想,虽然要开发成一门完备的脚本语言确实比较麻烦。但是在一些网络端的大型项目中,通过配置文件 + ClassLoader + 反射机制结合形成的这种软件解耦和方式已经用得比较普遍了。

所以,在此我不是在提出一种设想,而是在介绍业界处理此类问题的一种解决方案。

反射安全

文章读到这里,我想你应该由衷地感叹,Java反射机制实在是太强大了。但是,如果你有一些安全意识的话,就会发现Java这个机制强大得似乎有些过头了。前面我们提到,Java反射甚至可以访问private方法和属性。为了让大家对Java反射有更全面的了解,树立正确的人生观价值观,本小节将对Java的安全问题做一个概要性的介绍。

相对于C++来说,Java算是比较安全的语言了。这与它们的运行机制有密切的关系,C++运行于本地,也就是说几乎所有程序的权限理论上都是相同的。而Java由于是运行于虚拟机中,而不直接与外部联系,所以实际上Java的运行环境是一个“沙盒”环境。

Java的安全机制其实是比较复杂的,至少对于我来说是如此。作为Java的安全模型,它包括了:字节码验证器、类加载器、安全管理器、访问控制器等一系列的组件。之前文中提到过,我把Android安全权限划分为三个等级:第一级是针对编译期的“@hide”标记;第二级是针对访问权限的private等修饰;第三级则是以安全管理器为托管的Permission机制。

Java反射确实可以访问private的方法和属性,这是绕过第二级安全机制的方法(之一)。它其实是Java本身为了某种目的而留下的类似于“后门”的东西,或者说是为了方便调试?不管如何,它的原理其实是关闭访问安全检查。

如果你具有独立钻研的精神的话,你会发现之前我们提到的FieldMethodConstructor类,它们都有一个共同的父类AccessibleObject AccessibleObject 有一个公共方法:void setAccessible(boolean flag)。正是这个方法,让我们可以改变动态的打开或者关闭访问安全检查,从而访问到原本是private的方法或域。另外,访问安全检查是一件比较耗时的操作,关闭它反射的性能也会有较大提升。

不要认为我们绕过了前两级安全机制就沾沾自喜了,因为这两级安全并不是真正为了安全而设置的。它们的作用更多的是为了更好的完善规则。而第三级安全才是真正为了防止恶意攻击而出现的。在这一级的防护下,你甚至可能都无法完成反射(ReflectPermission),其他的一切自然无从说起。

对于这一级,我的了解还太少,并且也与本文的主题相关甚少。以后有机会,深入学习之后再聊吧!


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java反射机制的学习 的相关文章

  • TNN行业首发Arm 32位 FP16指令加速,理论性能翻倍

    转自 https cloud tencent com developer article 1774206 https www cnblogs com zhangshenghui p 11825760 html FP16是半精度浮点格式 相比
  • Android中Acition和Category常量表

    Action Action常量 对应字符串 简单说明 ACTION MAIN android intent action MAIN 应用程序入口 ACTION VIEW android intent action VIEW 显示指定数据 A
  • assert在debug 和 release版本中的区别

    转自 https blog csdn net panfengsoftware article details 8910468 debug版本与release的不同点 debug版本中含有调试信息 不会对程序进行优化 assert相应的宏会被
  • Tensorflow的Bazel编程(二)

    转自 http blog csdn net langb2014 article details 54312697 安装官网 https bazel build versions master docs tutorial Java html
  • Android-打包AAR步骤以及最为关键的注意事项

    转自 https www jianshu com p f391d0a6691e 简介 最近因为项目的要求 需要把开发的模块打包成aar 供其他项目调用 在搞了一段时间后 发现这里还是有很多需要注意的地方 所以记录一下 帮助大家不要走弯路 首
  • Android系统运动传感器

    转自 https blog csdn net liang123l article details 53992197 Android平台提供了多种感应器 让你监控设备的运动 传感器的架构因传感器类型而异 重力 线性加速度 旋转矢量 重要运动
  • android studio 安装说明

    转自 http www cnblogs com liuhongfeng archive 2015 12 30 5084896 html 1 下载android studio 含SDK版本 http www android studio or
  • 纯手工gcc 编译android native Cpp代码

    纯手工gcc 编译android native Cpp代码 api level 19 32位 编译成功 api level 19 home charlie android tool android ndk r10e toolchains a
  • 解决camera1 onPreviewFrame()会阻塞UI线程

    转自 https blog csdn net qq 31939617 article details 86360335 https www huaweicloud com zhishi arc 13664997 html 注意 onPrev
  • 各国语言对应翻译表

    为了工作方便 自己做了一个地区语言的英文翻译 让自己可以更快的找到自己需要的地方 同时 分享给大家 谢谢 中文 各国语言 翻译 序号 中文 翻译 1 阿尔巴尼亚语 2 阿拉伯语 3 阿姆哈拉语 4 阿塞拜疆语 Az rbaycan 5 爱尔
  • Android:手把手带你了解实用的Android Jetpack

    转自 https blog csdn net carson ho article details 104243841 前言 在2018年 Google I O 大会上发布了一系列辅助Android开发者开发的实用工具集合 Jetpack 今
  • Nv21转Bitmap(高效率转化)

    转自 https blog csdn net qq1137830424 article details 81980673 版权声明 本文为博主原创文章 遵循 CC 4 0 BY SA 版权协议 转载请附上原文出处链接和本声明 本文链接 ht
  • java static 静态方法的使用 注意事项

    定义为 static function1 function1 中不能引用this或super 在android 中这样用的话 会出现以下的报错 W dalvikvm 2783 JNI WARNING instance fieldID 0x5
  • Android性能调优工具TraceView介绍

    转自 http www trinea cn android android traceview 本文主要介绍Android性能调优工具TraceView的使用及通过其确定性能点 目前性能优化专题已完成以下部分 性能优化总纲 性能问题及性能调
  • 在Android Studio中下载Android SDK的两种方式(第二种好用)

    转自 https www cnblogs com mxj961116 p 10423479 html Android studio下载地址 http www android studio org 方式一 设置HTTP Proxy1 打开Se
  • Android数据的四种存储方式SharedPreferences、SQLite、ContenProvider

    作为一个完整的应用程序 数据存储操作是必不可少的 因此 Android系统一共提供了四种数据存储方式 分别是 SharePreference SQLite Content Provider File 由于Android系统中 数据基本都是私
  • Android开发使用OpenCv中JavaCameraView预览图左旋90度问题

    转自 https blog csdn net yd yandong article details 52698696 本文参考地址 http stackoverflow com questions 14816166 rotate camer
  • Java反射机制的学习

    转自 http www cnblogs com keis archive 2011 03 29 1998736 html Java反射机制是Java语言被视为准动态语言的关键性质 Java反射机制的核心就是允许在运行时通过Java Refl
  • Android APP应用启动页白屏(StartingWindow)优化

    转自 https www cnblogs com whycxb p 9312914 html 本人采用这种方法没有效果 启动图片出来第一帧 我应用的第一帧也出来了 启动背景颜色没有调试出来 Theme AppCompat Light Dar
  • android 反射机制和反射调用方法

    对于android 中很多类没有开放出来 考虑到这些API不稳定 后续有可能会更改 所有没有在SDK中暴露出来给用户使用 但是我们在开放的过程中还是需要使用到一些android 系统中未开放出来的class 这时候我们就可以通过反射机制来调

随机推荐

  • 通配符

    1 通配符 用来匹配文件名或目录 匹配文件内容用正则表达式 匹配任意一个字符 匹配0个或任意多个字符 也就是可以匹配任何内容 匹配括号中的任意一个字符 eg abc 匹配一个字符 或a 或b 或c 匹配括号中任意一个字符 代表一个范围 eg
  • 词向量的运算与Emoji生成器

    本文参考参考 没有对框架内容进行学习 旨在学习思路和方法 1 词向量运算 之前学习RNN和LSTM的时候 输入的语句都是一个向量 比如恐龙的名字那个例子就是将一个单词中的字母按顺序依次输入 这对于一个单词的预测是可行的 但是对于想让机器学习
  • Qt - MVC模型/视图编程

    MVC模型 视图编程 Qt中的模型 视图架构用来实现大量的数据存储 处理及显示 MVC Model View Controller 包括了3个组件 模型 Model 是应用对象 用来表示数据 视图 View 是模型的用户界面 用来显示数据
  • mac安装eclipse报错:Failed to create the Java Virtual Machine

    目录 1 报错场景 2 解决办法 1 查看本机安装的JAVA环境 2 修改info plsit文件 1 报错场景 macosx安装Eclipse的时候报错 Failed to create the Java Virtual Machine
  • @InitBinder解析和@ModelAttribute参数注入分析

    当我们请求 hello时 传参数u username如何注入到user中的username 样例 Controller public class HelloController RequestMapping hello public Str
  • Activiti7与SpringBoot整合开发

    SpringBoot 整合 Activti7 的具体步骤大概包括以下4步 1 添加 SpringBoot 整合 Activti7 的相关jar包 2 添加 SpringSecurity 安全框架的整合配置信息 3 使用 Activti7 新
  • 用递归解决八皇后问题

    单纯用递归解决该问题 就是利用一个一维数组表示出每种解 例如arry n i 其中n表示第n行的棋子 而 i 表示该 行的棋子所在列的位置 该问题可以用贪心算法进行优化 这是针对初学者练习递归时的一种解决办法 该代码并不是为了优化解决问题
  • flutter 开发踩坑集

    一 TextField设置高度后 文字无法居中 解决方案 TextField style TextStyle decoration InputDecoration prefixIcon ImageUtils getImage search
  • 区块链技术发展现状与展望 论文阅读摘要(袁勇、王飞跃)

    阅读摘要
  • 前端代码审查和测试

    检查代码的概念和过程 来自百度回答 https zhidao baidu com question 499002410583455364 html 1 代码检查法 1 桌面检查 这是一种传统的检查方法 由程序员检查自己编写的程序 程序员在程
  • GPT带我学-设计模式-命令模式

    1 你知道设计模式的命令模式吗 是的 我知道设计模式中的命令模式 命令模式是一种行为型设计模式 它将请求封装成一个对象 从而允许使用不同的请求 队列或日志来参数化其他对象 命令模式还支持撤销操作 并且可以提供事务的实现 在命令模式中 有四个
  • 机器学习——RBF神经网络

    RBF神经网络 本文部分资料与案例来源 MATLAB神经网络43个案例分析 RBF神经网络简述 再介绍RBF神经网络之前我们先来看一下径向基函数 RBF 在百度百科上 RBF定义如下 径向基函数是一个取值仅仅依赖于离原点距离的实值函数 也就
  • 未能加载文件或程序集“Newtonsoft.Json, Version=4.5.0.0"[已解决]

    前两天升级系统架构 升级后打开网页报错了 详细信息如下 未能加载文件或程序集 Newtonsoft Json Version 4 5 0 0 Culture neutral PublicKeyToken 30ad4fe6b2a6aeed 或
  • PHP架构师成长路线,PHP架构师要求

    在软件开发圈 架构师 是一个受万人追捧的头衔 架构师给人的感觉是站在软件系统后面指点江山的诸葛亮 一个系统的如何运作 运作得如何 架构师都能提前设想出来 然而 梦想是美好的 现实却是残酷的 很多人在实际工作后就会发现 梦想是成为大牛 但做的
  • 当对比学习遇上prompt,擦出了怎样的火花……

    细数最近NLP领域的热门关键词 transformer 多模态 预训练 还有不得不提的prompt 本质上说 prompt是一种激发语言模型中知识的手段 随着prompting技术的大火 有越来越多的研究者在思考 Prompt 除了让这个方
  • vue3 antd pro 框架动态路由

    此框架中路由权限使用了两种方法 主要介绍第二种方法 从路由表构建路由 前端对比后端权限字段过滤静态路由表 即 前端配置好全部的路由表 然后根据权限来与后端获取到的进行对比 最终展示对比后的数据 从后端获取路由表结构体 并构建前端路由 从后端
  • ubuntu的使用--系统目录篇(文末附Desktop目录位置)

    Ubuntu的Desktop 桌面 的目录是什么 ubuntu下的系统目录是什么样子的 1 cd命令技巧 直接进入用户的home目录 cd 进入上一个目录 cd 进入当前目录的上一层目录 cd 进入当前目录的上两层目录 cd 2 每次初始打
  • navicat 传输和同步

    同步 如果表存在 数据相同的则留 不同的则删除 然后插入目的表不存在的数据 同步相当于两个数据库表的数据拿出来比对是否有差异 传输 直接删表 插入源表数据 传输是一个数据表的数据进行插入 优缺点 这样比较的话 同步占内存但是快 适合数据量少
  • IDA反编译的几个注意和技巧

    IDA逆向程序的经验总结 关于一些类型转换以及指针和地址的总结 关于F5汇编代码不能转成c的伪代码的几个问题总结 1 jmpout的问题 2 positive sp value has been found 的问题 3 call analy
  • Java反射机制的学习

    转自 http www cnblogs com keis archive 2011 03 29 1998736 html Java反射机制是Java语言被视为准动态语言的关键性质 Java反射机制的核心就是允许在运行时通过Java Refl