3. javap javap 主要用于帮助开发者深入了解 Java 编译器的机制,主要选项有: -c:分解方法代码,即显示每个方法具体的字节码 -public | protected | package...// Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 30: iload...// Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 74: aload...// Method java/lang/StringBuilder.toString:()Ljava/lang/String; 86: invokevirtual #17...// Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 107: aload
非 String 对象:通过调用String.valueOf方法,如果是 null 对象,就返回”null”,否则调用对象的toString方法。... ()V ALOAD 1 INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder...INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder; INVOKEVIRTUAL...java/lang/StringBuilder.toString ()Ljava/lang/String; ASTORE 1 L2 LINENUMBER 29 L2 GETSTATIC java.../lang/System.out : Ljava/io/PrintStream; ALOAD 1 INVOKEVIRTUAL java/io/PrintStream.print (Ljava/lang
非 String 对象:通过调用String.valueOf方法,如果是 null 对象,就返回"null",否则调用对象的toString方法。... ()V ALOAD 1 INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder...INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder; INVOKEVIRTUAL...java/lang/StringBuilder.toString ()Ljava/lang/String; ASTORE 1L2 LINENUMBER 29 L2 GETSTATIC java/lang.../System.out : Ljava/io/PrintStream; ALOAD 1 INVOKEVIRTUAL java/io/PrintStream.print (Ljava/lang/String
非 String 对象:通过调用String.valueOf方法,如果是 null 对象,就返回"null",否则调用对象的toString方法。... ()V ALOAD 1 INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder...INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder; INVOKEVIRTUAL...java/lang/StringBuilder.toString ()Ljava/lang/String; ASTORE 1 L2 LINENUMBER 29 L2 GETSTATIC java/lang.../System.out : Ljava/io/PrintStream; ALOAD 1 INVOKEVIRTUAL java/io/PrintStream.print (Ljava/lang/String
":(Ljava/lang/String;)V 26: invokevirtual #10 // Method java/lang/StringBuilder.append...:(Ljava/lang/String;)Ljava/lang/StringBuilder; 29: new #7 // class java...:(Ljava/lang/String;)Ljava/lang/StringBuilder; 41: invokevirtual #12 // Method...java/lang/StringBuilder.toString:()Ljava/lang/String; 44: astore_2 45: return } 看到了没有?...s1直接调用了String的构造方法。
:(I)Ljava/lang/Integer; : areturn LineNumberTable: line : java.lang.Number...lang.String> ......省略部分结果.........void set(java.lang.String); descriptor: (Ljava/lang/String;)V flags: Code: stack=,.../String : invokevirtual #3 // Method set:(Ljava/lang/String;)V : return...这个方法就起了一个桥接的作用,它所做的就是把对自身的调用通过invokevirtual指令再调用方法void set(java.lang.String)。 编译器这么做的原因是什么呢?
make.exe 3、java开发 直接使用eclipse生成一个mvn项目,以这个最简项目开始入手 使用mvn编译出jar给c调用,参考maven将所有的依赖打成一个包,确保依赖没有问题,验证方法...;mytest.jar"; 这个参数里面的分号不能搞错,否则总是找不到java的类 5、java函数返回值只能是string 其他类型一定得不到返回值,只好老老实实把其他类型转换为string返回...函数执行异常返回值也拿不到 好的习惯是给java代码增加try catch,并且打印异常错误,从而能够快速发现问题,否则就是干着急也看不出问题在哪里,5和6两个问题基本耗费了我一天时间才解决 7、jvm.dll找不到的问题.../lang/String;)V"); if(main_method == NULL) { printf("can't find main_method\n");.../lang/String;Ljava/lang/String;)Ljava/lang/String;"); if (abiEncode_method == NULL) { printf
#12 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder...#12 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder...// Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 46: ldc...1.2 Public的方法都是复制一份数据 String有很多public方法,要想维护这么多方法下的不可变需要付出代价。每次都将创建新的String对象。...如果String是mutable,那么修改属性后,其hashcode也将改变。这样导致在HashMap中找不到原来的value。
Format.DIRECTORY); try { //将该文件放入到目标目录中,这步骤必须实现,否则会导致dex文件找不到该文件.../lang/String;Ljava/lang/String;)I", false); mv.visitInsn(Opcodes.POP); } @Override.../lang/String;Ljava/lang/String;)I", false); mv.visitInsn(Opcodes.POP); super.onMethodExit.../lang/String;Ljava/lang/String;)I", false); methodVisitor.visitInsn(POP); Label.../lang/String;Ljava/lang/String;)I", false); methodVisitor.visitInsn(POP); 然后将其放入到onMethodExit函数中,就可以了
java.lang.Number get(); descriptor: ()Ljava/lang/Number; flags: ACC_BRIDGE, ACC_SYNTHETIC...lang.String> ......省略部分结果.........void set(java.lang.String); descriptor: (Ljava/lang/String;)V flags: Code: stack=0,.../String 5: invokevirtual #3 // Method set:(Ljava/lang/String;)V 8:...这个方法就起了一个桥接的作用,它所做的就是把对自身的调用通过invokevirtual指令再调用方法void set(java.lang.String)。 **编译器这么做的原因是什么呢?
image.png 事实上这里还有隐藏逻辑,看其中源码,你会发现,卧槽,我都找不到定义jni的方法名,熟悉jni的同学知道,jni方法名是Java+ 全类名 命名,可是你会发觉比如你想找到_start方法.../lang/String;[Ljava/lang/String;[Ljava/lang/String;)V", (void *) IjkMediaPlayer_setDataSourceAndHeaders...(void *) IjkMediaPlayer_native_finalize }, { "_setOption", "(ILjava/lang/String;Ljava..."(I)Ljava/lang/String;", (void *) IjkMediaPlayer_getColorFormatName }, { "_getVideoCodecInfo",...", "()Ljava/lang/String;", (void *) IjkMediaPlayer_getAudioCodecInfo }, { "_getMediaMeta"
UnsatisfiedLinkError 异常信息: Process: com.woosiyuan.cruiserobot.robot, PID: 8358 java.lang.UnsatisfiedLinkError...: Native method not found: android_serialport_api.SerialPort.openTest:(Ljava/lang/String;II)Ljava/io/...找不到openTest这个Native方法导致的错误,so库里面的方法路径、方法名称都是固定的,java里面如果不对应就会导致这个错误,可以通过查看your.so文件来确定对错,文本编辑器用十六进制方式打开...(图画的太丑了,请轻喷,哈哈) 画红线的地方找到了两个Native方法: open和close,然后对应报错class里声明的Native方法 ?
[]{"equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone",...(new String[]{"sayHello", "(Ljava/lang/String;)Ljava/lang/String;"}, (var1 = Class.forName("club.throwable.cglib.SampleClass.../lang/String;)Ljava/lang/String;", "sayHello", "CGLIB$sayHello$0"); } //这个方法就是直接调用原来的被代理类(父类...: if (var10000.equals("sayHello(Ljava/lang/String;)Ljava/lang/String;")) {.../lang/String;)Ljava/lang/String;")) { return 16; } break;
$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke...:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke...Ljava/lang/String;>; private static void lambda$main$0(java.lang.String); descriptor: (Ljava/.../lang/String; } 通过字节码可以看出,调用lambda方法时使用了invokedynamic,该字节码命令是为了支持动态语言特性而在Java7中新增的。.../lang/String;)V #47 (Ljava/lang/String;)V ?
方法还是会先去查询常量池中是否有已经存在,如果存在,则返回常量池中的引用,这一点与之前没有区别,区别在于如果在常量池找不到对应的字符串则不会再将字符串拷贝到常量池,而只是在常量池中生成一个对原字符串的引用...[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=1...:(Ljava/lang/String;)Ljava/lang/StringBuilder; 14: ldc #6 // String.../lang/String;)Ljava/lang/StringBuilder; 19: invokevirtual #7 // Method java/...lang/StringBuilder.toString:()Ljava/lang/String; 22: astore_2 23: return LineNumberTable
#43.#44 // java/io/PrintStream.println:(Ljava/lang/String;)V // Jathonkatu 方法符号引用 调用printStream...$0 // Jathonkatu 方法名 #26 = Utf8 (Ljava/lang/String;)V // Jathonkatu String变量值 #27...lang/String;)V #36 = MethodType #26 // (Ljava/lang/String;)V // Jathonkatu 方法类型...[]); //Jathonkatu main方法 descriptor: ([Ljava/lang/String;)V // Jathonkatu 描述符 flags: ACC_PUBLIC...$main$0:(Ljava/lang/String;)V #36 (Ljava/lang/String;)V
前言 在之前的面试经历中,对于String的考察还是挺频繁的,大致考察以下几个知识点: String 常量池 new String() == 和 equals 的区别 native 方法 String.intern...我去证实了,发现确实调用了 append 方法,但是当时没有 调用toString()方法,我很疑惑。...:(Ljava/lang/String;)Ljava/lang/StringBuilder; : ldc # // String.../lang/String; str1 Ljava/lang/String; str2 Ljava...java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; : ldc #6
":(Ljava/lang/String;)V #25 = NameAndType #5:#26 // "":(Ljava/lang/String.../String; #36 = NameAndType #37:#38 // valueOf:(Ljava/lang/Object;)Ljava/lang/String;...// Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String; 46: invokespecial #39...接口没有,属性没有,方法两个(这里有一个疑问,方法为啥是两个啊,只看见一个一个main 方法啊),我们点进去方法看一下 ? ?...我们开始讲方法一。 ? 方法名称main 方法, 返回类型string , 访问修饰符public static 的。
} 当调用intern方法时,如果常量池已经包含一个equals此String对象的字符串,则返回池中的字符串 当调用intern方法时,如果常量池没有一个equals此...:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String.../String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite...String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;...;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke
#7 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder...// java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; #8 = Methodref...= Utf8 Ljava/lang/Object;Ljava/lang/ComparableLjava/lang/String;>;Ljava/io/Serializable...(Ljava/lang/String;)Ljava/lang/StringBuilder; #78 = Utf8 (I)Ljava/lang/StringBuilder;...;Ljava/lang/ComparableLjava/lang/String;>;Ljava/io/Serializable; SourceFile: "MethodInnerStructTest.java