阅读源代码(部分源码)1.String:
首先所定义的类型是私有的,从源码来分析的话:
/**The value is used for character storage. */ private final char value[]; /** The count is the number of characters in the String. */ private final int count;
从图上来看,首先先定义了字符数组value来存储字符,count是String的长度,这里得注意到String类是final的,不可以被继承,而且private final char value[];,只能赋值一次,赋值后就不能变了,只有从新生成一个String对象。
public String concat(String str) { int otherLen = str.length(); if (otherLen == 0) { return this; } char buf[] = new char[count otherLen]; getChars(0, count, buf, 0); str.getChars(0, otherLen, buf, count); return new String(0, count otherLen, buf); }
这段代码是用来连接数组的,以char数组做容器,从this和str分别取出char放入buf内,注意getChars方法(!!该方法的作用是将当前字符串从start到end-1位置上的字符复制到字符数组c中,并从c的offset处开始存放)的第四个参数,这个也就是说buf从count个开始拷贝。也就是说把两个string的char放在了一个char数组内,再返回一个新的String对象。
public boolean equals(Object anObject)
这个就不上源码了,简述就是两个char数组的里面的字符比较比较。
2.Integer:
Integer 类在对象中包装了一个基本类型 int 的值。该对象包含一个 int 类型的字段。
此外,该类提供了多个方法,能在 int 类型和 String 类型之间互相转换,还提供了处理 int 类型时非常有用的其他一些常量和方法。
首先它的定义是这样的:
public final class Integer extends Number implements Comparable<Integer>
我们可以知道以下几点:
1、Integer类不能被继承
2、Integer类实现了Comparable接口,所以可以用compareTo进行比较并且Integer对象只能和Integer类型的对象进行比较,不能和其他类型比较(至少调用compareTo方法无法比较)。
3、Integer继承了Number类,所以该类可以调用longValue、floatValue、doubleValue等系列方法返回对应的类型的值。
在Integer类中定义两个私有属性
private final int value; private static final long serialVersionUID = 1360826667806852920L;
其中serialVersionUID和序列化有关,而value属性就是Integer对象中真正保存int值的。
但是常写代码的小伙伴就会有这种问题了,
Integer i = new Integer(10); i = 5;
最后结果我们都知道是5,那么i=5这一步做了什么呢?
运用反编译器(上节提过),代码会变成i = Integer.valueOf(5)这样子,首先先让我们看一下valueOf(int i)是怎么样给变量赋值的。
这有一段静态代码块:
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; }
也就是说,当Integer被加载时,就新建了-128到127的所有数字并存放在Integer数组cache中。
再回到valueOf代码,可以得出结论。当调用valueOf方法(包括后面会提到的重载的参数类型包含String的valueOf方法)时,如果参数的值在-127到128之间,则直接从缓存中返回一个已经存在的对象。如果参数的值不在这个范围内,则new一个Integer对象返回。
3.Enum:首先是定义
public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable
我们可以看到abstract这个修饰,说明Enum是抽象类,所以其不能被实例化,而且通过操作发现Enum类是无法被继承的,反编译后会发现采用enum声明后,该类会被编译器加上final声明,故该类是无法继承的。
之后阅读源码发现Enum实现了Serializable接口,可以序列化。 Enum实现了Comparable接口,可以进行比较,默认情况下,只有同类型的enum才进行比较,要实现不同类型的enum之间的比较,只能复写compareTo方法。
而对于泛型<E extends Enum<E>>,首先我们先来“翻译”一下这个Enum<E extends Enum>到底什么意思,然后再来解释为什么Java要这么用。 我们先看一个比较常见的泛型:List。这个泛型的意思是,List中存的都是String类型,告诉编译器要接受String类型,并且从List中取出内容的时候也自动帮我们转成String类型。 所以Enum<E extends Enum>可以暂时理解为Enum里面的内容都是E extends Enum类型。 这里的E我们就理解为枚举,extends表示上界,比如: List<? extends Object>,List中的内容可以是Object或者扩展自Object的类。这就是extends的含义。 所以,E extends Enum表示为一个继承了Enum类型的枚举类型。 那么,Enum<E extends Enum>就不难理解了,就是一个Enum只接受一个Enum或者他的子类作为参数。相当于把一个子类或者自己当成参数,传入到自身,引起一些特别的语法效果。
对于Enum中的属性
有两个成员变量,一个是名字(name),一个是序号(ordinal)。 序号是一个枚举常量,表示在枚举中的位置,从0开始,依次递增。
private final String name; public final String name() { return name; } private final int ordinal; public final int ordinal() { return ordinal; }
当然虽然Enum是一个抽象类,虽然不能被实例化,但它的构造函数还是有的。
推荐阅读:
蚂蚁金服春招总结篇(1)
蚂蚁金服春招总结篇(2)
原文:https://blog.csdn.net/qq_40901379/article/details/83789683
,