java 会默认做的那些事
这是一个基础类的源码文件
public class Demo {
public static void main(String[] args) {
System.out.println("HelloWorld!");
}
}
反编译过后的
# javap -c Demo
Compiled from "Demo.java"
public class Demo extends java.lang.Object{
public Demo();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3; //String helloWorld!
5: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
}
反编译过后可以看到
- 自定义一个类会默认继承
java.lang.Object
, 这也是 Object 利用多态能接受任意对象的原因 - 一个类中会默认有一个构造方法,他的默认实现是调用到父类的空构造方法
- 当你自定义了一个构造方法后jdk就不会默认给你加空构造了
- 这里要注意构造方法中
super(...)
一定是第一行代码,就算你不写super(...)
她会默认调用父类的空构造
接下来在来看一段源码
import java.util.Arrays;
import java.util.List;
public class Demo {
public static void main(String[] args) {
List<String> list = Arrays.asList("Java", "JavaME", "JavaSE", "JavaEE");
String data = "";
for (String s : list) {
data += s + ",";
}
System.out.println(data);
}
}
反编译后的结果为
# javap -c Demo
Compiled from "Demo.java"
public class Demo extends java.lang.Object{
public Demo();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_4
1: anewarray #2; //class java/lang/String
4: dup
5: iconst_0
6: ldc #3; //String Java
8: aastore
9: dup
10: iconst_1
11: ldc #4; //String JavaME
13: aastore
14: dup
15: iconst_2
16: ldc #5; //String JavaSE
18: aastore
19: dup
20: iconst_3
21: ldc #6; //String JavaEE
23: aastore
24: invokestatic #7; //Method java/util/Arrays.asList:([Ljava/lang/Object;)Ljava/util/List;
27: astore_1
28: ldc #8; //String
30: astore_2
31: aload_1
32: invokeinterface #9, 1; //InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
37: astore_3
38: aload_3
39: invokeinterface #10, 1; //InterfaceMethod java/util/Iterator.hasNext:()Z
44: ifeq 86
47: aload_3
48: invokeinterface #11, 1; //InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
53: checkcast #2; //class java/lang/String
56: astore 4
58: new #12; //class java/lang/StringBuilder
61: dup
62: invokespecial #13; //Method java/lang/StringBuilder."<init>":()V
65: aload_2
66: invokevirtual #14; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
69: aload 4
71: invokevirtual #14; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
74: ldc #15; //String ,
76: invokevirtual #14; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
79: invokevirtual #16; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
82: astore_2
83: goto 38
86: getstatic #17; //Field java/lang/System.out:Ljava/io/PrintStream;
89: aload_2
90: invokevirtual #18; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
93: return
}
从反编译中能看出
-
关于字符串拼接
- 在少量字符串拼接时jdk会默认给我们转成StringBuilder来实现,这也是为什么少量字符串拼接可以使用String对象的原因
-
在使用
for (String s : list) {}
时- 会默认调用到
java.util.Iterator
接口中的方法 -
我们自定义类如果想使用这种迭代方式就需要满足一下两种条件
- 是集合架构中的一员
- 自定义实现
Iterator
中的方法
- 会默认调用到
自定义枚举类
public enum Demo {
SUCCESS(0, "成功"),
ERROR(1, "失败");
private Integer code;
private String msg;
Demo(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
}
反编译枚举后可以看到
# javap Demo
Compiled from "Demo.java"
public final class Demo extends java.lang.Enum{
public static final Demo SUCCESS;
public static final Demo ERROR;
public static final Demo[] values();
public static Demo valueOf(java.lang.String);
static {};
}
从反编译结果中可以看到
- 枚举类实际上是一个加了
final
class 他会默认继承自java.lang.Enum
- 每一个枚举类型都会转成 public static final 的对象
自定义注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Demo {
String value();
}
反编译的结果
# javap Demo
Compiled from "Demo.java"
public interface Demo extends java.lang.annotation.Annotation{
public abstract java.lang.String value();
}
从反编译结果中可以看出
- 可以看出注解会默认继承
java.lang.annotation.Annotation
- 一个属性就是一个抽象方法
还有一些常识
-
Java
会默认导入java.lang
包- 这个自动导入使得我们在使用
Integer,Object,System
等类的时候不需要手动导包
- 这个自动导入使得我们在使用
-
System.out.println();
的时候会默认调用到对象中的toString();
方法 -
HashSet
在存储时会默认调用到对象的hashCode()::equals()
方法-
HashSet
在判断元素重复时借助了hashCode()
的hash算法来筛选掉一批不重复的数据 - 在hash值相等的时候在借助
equals()
判断是否重复如果重复就不录入了 - 为什么要使用到两个方法来判断是否重复这里是hash算法的一个特点了, 在
HashMap
中如果hash值相等值不相等就会在hash表中形成一个hash链
-
-
TreeSet
在存储时,要求元素实现Comparable
接口-
TreeSet
使用了树状结构需要使用到java.lang.Comparable#compareTo
方法的返回值 - 通过返回来决定元素是否重复: [
0元素重复
,<0左子树
,>0右子树
]
-
Integer 的自动封装和catch
先来看一段源码代码
Integer val1 = 1;
Integer val2 = 1;
System.out.println(val1 == val2);
Integer val3 = 996;
Integer val4 = 996;
System.out.println(val3 == val4);
反编译结果
# javap -c Demo
Compiled from "Demo.java"
public class Demo {
public Demo();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_1
1: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
4: astore_1
5: iconst_1
6: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
9: astore_2
10: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
13: aload_1
14: aload_2
15: if_acmpne 22
18: iconst_1
19: goto 23
22: iconst_0
23: invokevirtual #4 // Method java/io/PrintStream.println:(Z)V
26: sipush 996
29: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
32: astore_3
33: sipush 996
36: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
39: astore 4
41: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
44: aload_3
45: aload 4
47: if_acmpne 54
50: iconst_1
51: goto 55
54: iconst_0
55: invokevirtual #4 // Method java/io/PrintStream.println:(Z)V
58: return
}
- 在Integer类型自动拆装箱实际上是使用了
Integer.valueOf()
方法 - 我们可以通过了解
valueOf()
的源码来理解 Integer-128~127
缓存
Integer.valueOf() 的实现
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
Integer缓存核心实现
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
内部类访问变量时的隐式操作
public static void main(String[] args) {
String str = "hello";
new Transfer() {
@Override
void transfer() {
System.out.println(str);
str = "world!";
System.out.println(str);
}
}.transfer();
}
public static abstract class Transfer {
abstract void transfer();
}
- 在案例中 String 类型的 str 实际上会隐式的给我们加上
final
修饰

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
从“草原牛”到“数字牛”:蒙牛数智化转型棋至中盘
从牧场牛奶(“Grass”)到杯中牛奶(“Glass”),蒙牛集团的数智化转型之道。 乳品行业是国内实施信息化最早的行业之一。 在蒙牛,每一盒牛奶从牧场到工厂,再到终端门店、消费者,都要经过6到7个环节——这就意味着,必须有一套完整可靠的信息化系统才可以解决商品、财务、信息流等准确的传递。 然而,信息化永远都是第一步,因为这些结构化数据记录的都是发生过的事情;为了让这些“过去”的数据能够对未来产生价值,“我们联手阿里云引进了各类物联网设备,增加了大量非结构化的外部数据源,用大数据建模、测试、分析,进而预测、预警,从事后的分析到事中的洞察和事先的预测,这就是蒙牛正在开展的数字智能化转型”,蒙牛集团CIO张决表示。 壹 “智慧牧场”:从“草原牛”到“数字牛” 在2020年1月的冬季达沃斯论坛上,蒙牛集团CEO卢敏放表示,“一盒蒙牛牛奶背后有170兆字节的数据”。 从牧场牛奶(“Grass”)到杯中牛奶(“Glass”),对源头奶牛的精确了解是第一步。在智能脖环的辅助下,奶牛的各类数据会自动上传并进行数据分析。 “在部分先进的牧场,我们的奶牛是有计步器的,根据它们每天的步数,我们可以判断它们...
-
下一篇
C#多线程(4):进程同步Mutex类
C#多线程(4):进程同步Mutex类 目录Mutex 类构造函数和方法系统只能运行一个程序的实例解释一下上面的示例接替运行进程同步示例另外Mutex 类Mutex 中文为互斥,Mutex 类叫做互斥锁。它还可用于进程间同步的同步基元。 Mutex 跟 lock 相似,但是 Mutex 支持多个进程。Mutex 大约比 lock 慢 20 倍。 互斥锁(Mutex),用于多线程中防止两条线程同时对一个公共资源进行读写的机制。 Windows 操作系统中,Mutex 同步对象有两个状态: signaled:未被任何对象拥有;nonsignaled:被一个线程拥有;Mutex 只能在获得锁的线程中,释放锁。 构造函数和方法Mutex 类其构造函数如下: 构造函数 说明Mutex() 使用默认属性初始化 Mutex类的新实例。Mutex(Boolean) 使用 Boolean 值(指示调用线程是否应具有互斥体的初始所有权)初始化 Mutex 类的新实例。Mutex(Boolean, String) 使用 Boolean 值(指示调用线程是否应具有互斥体的初始所有权以及字符串是否为互斥体的名称...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- MySQL数据库在高并发下的优化方案
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- Dcoker安装(在线仓库),最新的服务器搭配容器使用
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Docker快速安装Oracle11G,搭建oracle11g学习环境