字节码

Lambda表达式和匿名内部类区别

|▌冷眼眸甩不掉的悲伤 提交于 2020-01-13 00:31:43
所需类型不同 匿名内部类: 可以是接口,也可以是抽象类,还可以是具体类 Lambda表达式:只能是接口 使用限制不同 如果接口中有且仅有一个抽象方法,可以使用Lambda表达式,也可以使用匿名内部类 如果接口中多于一个抽象方法,只能使用匿名内部类,而不能使用Lambda表达式 实现方式不同 匿名内部类:编译之后,产生一个单独的。class字节码文件 Lambda表达式:变异之后,没有一个单独的。class字节码文件。对应的字节码会在运行的时候动态生成 来源: CSDN 作者: 0和1的尽头又是啥 链接: https://blog.csdn.net/qq_43205282/article/details/103946906

Javac 源码调试教程

烂漫一生 提交于 2020-01-12 14:00:37
环境搭建过程 环境备注:Intellij、JDK8 1、第一步下载导入 javac 的源码 如果不想从 openjdk 下载折腾,可以跳过第 1 步直接从我的 github 下载: github.com/arthur-zhan… OpenJDK 的下载方式为: 打开 hg.openjdk.java.net/jdk8/jdk8/l… ,点击左侧的 zip 或者 gz 进行下载。 在 Intellij 中新建一个 javac-source-code-reading 项目,把源码目录的 src/share/classes/com 目录整个拷贝到项目 src 目录下,删掉没用的 javadoc 目录。 2、找到 javac 主函数入口 代码在 src/com/sun/tools/javac/Main.java 运行这个 main 函数,因为没有加需要编译的源代码路径,不出意外应该会在控制台会输出下面的内容 新建一个 HelloWorld.java 文件,内容随缘,在启动配置的 Program arguments 里加入 HelloWorld.java 的绝对路径。 再次运行 Main.java,会在 HelloWorld.java 的同级目录生成 HelloWorld.class 文件。 3、加断点 在 Main.java 中打上断点,开始调试以后会发现不管怎么设置,调试都会进入 tool

Android方法数超出限定的问题(multiDex,jumboMode)

妖精的绣舞 提交于 2020-01-12 10:39:21
在Android项目开发中,项目代码量过大或通过引入很多jar导致代码量急剧增加,会出现错误: android.dex.DexIndexOverflowException: Cannot merge new index xxxx into a non-jumbo instruction! 错误出现的原因是 Android设定的方法数是65536个(DEX 64K problem),超过这个方法数,导致dex无法生成,就无法生成APK. 限制原因: 早期的Dalvik VM内部使用short类型变量来标识方法的id,就有了 最大方法数的限制65536。 解决方法: 删除不用的方法,删除不使用的jar。 分包 通过在defaultConfig中设置multiDexEnabled开启分包模式,分包之后的Dex就低于了限制数,保证了正常的打包。 1 defaultConfig { 2 multiDexEnabled=true 3 } 忽略方法数限制的检查 1 android.dexOptions { 2 jumboMode = true 3 } 设置dexOptions的,不做方法数限制的检查,这样做的缺点是apk无法再低版本的设备上面安装,会出现错误: INSTALL_FAILED_DEXOPT 关于 dexoptions 和 jumboMode 在stackoverflow中有一段描述

如何保护Python代码?

痞子三分冷 提交于 2020-01-12 04:10:37
我正在用 Python 开发一款软件,该软件将分发给我的雇主的客户。 我的雇主希望通过限时许可文件来限制软件的使用。 如果我们分发.py文件甚至.pyc文件,则很容易(反编译和)删除检查许可证文件的代码。 另一个方面是,我的雇主不希望我们的客户阅读该代码,因为担心该代码可能被盗或至少是“新颖的主意”。 有解决这个问题的好方法吗? 最好使用现成的解决方案。 该软件将在Linux系统上运行(因此,我认为py2exe不会成功)。 #1楼 我认为还有另一种方法可以保护您的Python代码; 混淆方法的一部分。 我相信有一个像Mount and Blade这样的游戏,或者某些东西改变了并重新编译了自己的python解释器(我认为它是开源的原始解释器),只是将OP代码表中的OP代码更改为与标准python OP不同代码。 因此python源代码未修改,但* .pyc文件的文件扩展名不同,并且操作码与公共python.exe解释器不匹配。 如果您检查了游戏数据文件,则所有数据均为Python源格式。 各种各样的恶作剧都可以通过这种方式与未成熟的黑客打成一片。 阻止一堆没有经验的黑客很容易。 这是您不可能击败的专业黑客。 但是我想象中的大多数公司都不会长时间聘请专业黑客(可能是因为事情被黑客入侵了)。 但是到处都是不成熟的黑客(以好奇的IT员工的身份阅读)。 例如,您可以在经过修改的解释器中

Class文件结构

允我心安 提交于 2020-01-11 23:00:14
class文件总体结构: 1.Magic Value(魔数) class文件的第一行的前四个字节 CA FE BA BE(十六进制) ,在JVM在执行class字节码文件的时候,会检查前四个字节是否为这个值,如果不是这个值就不是一个合法的java编译器编译过来的字节码文件,JVM就不会去执行它; 第一行的后四个字节为jdk的版本号 00 00(次版本) 00 34(主版本) ( 十六进制转换成十进制为52,代表jdk1.8 ); 2.CONSTANT_POOL(常量池) 3.访问标志 4.类索引 标识继承了那些类,实现了那些接口 5.字段表集合 用于描述接口或类中声明的变量 字段表结构 字段访问标志 6.方法表集合 7. 属性表集合 来源: CSDN 作者: Attention_0 链接: https://blog.csdn.net/Attention_0/article/details/103934558

JVM基础课一:类加载

橙三吉。 提交于 2020-01-11 18:10:11
JVM JVM虚拟机,可以看作软件模拟完整的硬件系统。 解释执行.class的字节码文件,在java中是通过javac命令来编译.java代码为字节码文件的 javap xxx.class 可以查看字节码文件 jvm上运行的应用程序都有一个特点,一次编写,到处运行,应用不在对底层操作系统,物理设置有依赖,而只依赖jvm,并且JVM还有自动内存管理,对多线程友好等特点。 jdk源码:http://jdk.java.net/java-se-ri/7。 字节码文件 字节码的指令集有不超过256条指令,大多数和类型相关。 例如,invokevirtual指调用对象的实例方法,会根据对象的实际类型进行分派,在运行期间确定,也称为动态分派。 类加载 类加载是指JVM加载.class的字节码文件到内存(元数据区,方法区)的过程,在java程序中主要涉及Class对象的建立,静态变量分配内存空间和赋值,static代码块的执行。 JVM对类加载是按需加载的,当执行new操作,static变量和方法使用,反射调用,Class.forName("…"),getClassLoader().loadClass()等操作时会触发类加载过程; 通过在启动参数中添加-verbose:class,-verbose:gc,-verbose:jni可以查看启动类加载,gc和本地方法调用的日志。 类加载的过程

jvm学习笔记(一)

前提是你 提交于 2020-01-11 12:28:21
一、java的运行原理 开发人员编写java代码(.java文件) 编译器将.java文件编译成字节码文件(.class文件) 字节码被装入内存,当字节码被装入内存之后,它就会被解释器解释执行或是被即时编译器有选择的转换成机器码执行 二、jvm体系结构 1、类装载(classLoader)子系统     根据给定的全限定名类名来装在.class文件的内容到Runtime Data Area中的method Area(方法区域)。 2、执行引擎(Execution Engine)子系统     执行引擎也叫做解释器(Interpreter),负责解释命令提交给操作系统执行。 3、本地接口(Native Interface)组件       本地接口的作用是融合不同的编程语言为JAVA所用,目前该方法使用的比较少,因为现在的异构领域间的通信很发达,比如socket、webservice等 4、运行数据域(RuntimeDataArea)组件       运行数据区是整个 JVM 的重点。我们所有写的程序都被加载到这里,之后才开始运行 4.1 Java Stack(栈)         栈是在线程创建的时候创建的,它的生命周期是跟随线程的生命周期的,线程结束栈内存就被释放了,所以栈不存在垃圾回收问题。栈主要用于存放引用和基本数据类型(八大基本数据类型)。当一个线程把栈内存用光了之后

lua源码阅读笔记与思路整理一

感情迁移 提交于 2020-01-11 03:41:41
由于工作需要用了很多年的lua编写各种逻辑处理模块,今天心血来潮,决定深入了解一下lua源码的实现,目的是方便自己的lua代码调试,省的每次都用print打印这种原始手段,本“长篇小说“ 主要弄懂以下的问题: 1 local , global, upvalue 的原理和实现,upvalue的查找和递归标记是什么? 2 Function是什么,执行过程如何,参数如何传递,怎么分配栈上空间? 3 循环结构的实现 4 模块的实现,closure是什么 5 各种元表的实现,基本类型的元表如何增加(lua内部职能给table加元表,number,string这些都需要外部增加) 6 各种库方法的实现,如debug, math, string, os库等,浏览一遍有个概念即可 7 判断和跳转的实现 8 钩子函数的实现和应用 9 报错是如何组织的,各项信息在哪里保存的,又如何获取? 10 lua常量是什么,为什么要共享同一份常量? 11 gc回收是什么,如何实现的,流程是什么? 12 table类型的存储和访问,分数组类型和哈希类型 万里执行始于足下:先从最简单的local变量开始: 一、主要流程先表述一下:解析lua语言,生成c代码 >>>>> 调用c代码 前面的各种函数调用封装,检测错误封装暂且不表,直接进入最终解析语法的开始函数这: f_parser(lua_State*L ,void*

从字节码角度分析装箱和拆箱

不羁的心 提交于 2020-01-11 01:48:08
一.拆箱和装箱的基本介绍 装箱和拆箱是Java中提供的两个有用的语法糖。 装箱是指将基本数据类型自动转换为它的包装器类型。如int到Integer的转换。 拆箱是指将包装器类型转换为对应的基本数据类型。如Integer到int的转换。 以下是一个例子: Integer num1 = 1000 ; int num2 = num1 ; 其中num1是一个Integer类型的对象,这里对它的赋值操作就是一个装箱的过程。 num2是一个基本类型int的变量,用num1给它赋值就是一个拆箱的过程。 二.拆箱和装箱的字节码实现 下面我们从字节码的角度看一下装箱和拆箱是如何实现的吧。 那么如何获取到Java代码的字节码呢?其实我们在使用javac对Java源代码进行编译后得到的class文件就是其字节码文件。 但是这个class文件是二进制形式存在的,是无法直接阅读的。所以还需要另外一个命令 javap帮我们把class文件解析为可读的形式 。 我们将以下代码保存在 test.java 文件中(这里省略了类目、main方法等): Integer num1 = 1000 ; int num2 = num1 ; javap 命令的使用 然后用javac进行编译,再用 javap -v 进行反编译。javap加上-v参数可以看到较为全面的信息。 javac test.java javap -v

Java编译期的优化

 ̄綄美尐妖づ 提交于 2020-01-10 04:11:27
语法糖 所谓的 语法糖 ,其实就是指 java 编译器把 *.java 源码编译为 *.class 字节码的过程中,自动生成和转换的一些代码,主要是为了减轻程序员的负担,算是 java 编译器给我们的一个额外福利(给糖吃嘛) 1 默认构造器 public class Candy1 { } 编译成class后的代码: public class Candy1 { // 这个无参构造是编译器帮助我们加上的 public Candy1 ( ) { super ( ) ; // 即调用父类 Object 的无参构造方法,即调用 java/lang/Object." < init > " : ( ) V } } 2 自动拆装箱 这个特性是 JDK 5 开始加入的, 代码片段1 : public class Candy2 { public static void main ( String [ ] args ) { Integer x = 1 ; int y = x ; } } 这段代码在 JDK 5 之前是无法编译通过的,必须改写为 代码片段2 : public class Candy2 { public static void main ( String [ ] args ) { Integer x = Integer . valueOf ( 1 ) ; int y = x .