对于关系操做符 ==html
对于使用 equals 方法,内部实现分为三个步骤:java
Java 中全部内置的类的 equals 方法的实现步骤均是如此,特别是诸如 Integer,Double 等包装器类。如如下 String
中的 equals
方法实现android
// String.java
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
复制代码
hashcode是系统用来快速检索对象而使用git
equals方法本意是用来判断引用的对象是否一致github
重写equals方法和hashcode方法时,equals方法中用到的成员变量也一定会在hashcode方法中用到,只不过前者做为比较项,后者做为生成摘要的信息项,本质上所用到的数据是同样的,从而保证两者的一致性面试
Java 基本类型占用的字节数安全
注:1字节(byte)=8位(bits)网络
多态是指父类的某个方法被子类重写时,能够产生本身的功能行为,同一个操做做用于不一样对象,能够有不一样的解释,产生不一样的执行结果。多线程
多态的三个必要条件:并发
而后可使用结合里氏替换法则进一步的谈理解
里氏替换法则 ---- 全部引用基类的地方必须能透明地使用其子类的对象
注意 在类中调用其余类时务必要使用父类或接口,若是不能使用父类或接口,则说明类的设计已经违背了LSP原则
注意 若是子类不能完整地实现父类的方法,或者父类的某些方法在子类中已经发生“畸变”,则建议断开父子继承关系,采用依赖、汇集、组合等关系代替继承
在项目中,采用里氏替换原则时,尽可能避免子类的“个性”,一旦子类有“个性”,这个子类和父类之间的关系就很难调和了, 把子类当作父类使用,子类的“个性”被抹杀——委屈了点;把子类单独做为一个业务来使用,则会让代码间的耦合关系变得扑朔迷离——缺少类替换的标准
StringBuffer 和 String 同样都是用来存储字符串的,只不过因为他们内部的实现方式不一样,致使他们所使用的范围不一样,对于 StringBuffer 而言,他在处理字符串时,如果对其进行修改操做,它并不会产生一个新的字符串对象,因此说在内存使用方面它是优于 String 的
StringBuilder 也是一个可变的字符串对象,他与 StringBuffer 不一样之处就在于它是线程不安全的,基于这点,它的速度通常都比 StringBuffer 快
String 字符串的拼接会被 JVM 解析成 StringBuilder 对象拼接,在这种状况下 String 的速度比 StringBuffer 的速度快
str +=”b”等同于 str = new StringBuilder(str).append(“b”).toString();
内部类使得多重继承的解决方案变得更加完整
使用内部类最吸引人的缘由是:每一个内部类都能独立地继承一个(接口的)实现,因此不管外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响
使用内部类才能实现多重继承
当咱们在建立某个外围类的内部类对象时,此时内部类对象一定会捕获一个指向那个外围类对象的引用,只要咱们在访问外围类的成员时,就会用这个引用来选择外围类的成员
在成员内部类中要注意两点,
静态内部类与非静态内部类之间存在一个最大的区别,咱们知道非静态内部类在编译完成以后会隐含地保存着一个引用,该引用是指向建立它的外围内,可是静态内部类却没有。没有这个引用就意味着:
匿名内部类用法
public class TryUsingAnonymousClass {
public void useMyInterface() {
final Integer number = 123;
System.out.println(number);
MyInterface myInterface = new MyInterface() {
@Override
public void doSomething() {
System.out.println(number);
}
};
myInterface.doSomething();
System.out.println(number);
}
}
复制代码
编译后的结果
class TryUsingAnonymousClass$1 implements MyInterface {
private final TryUsingAnonymousClass this$0;
private final Integer paramInteger;
TryUsingAnonymousClass$1(TryUsingAnonymousClass this$0, Integer paramInteger) {
this.this$0 = this$0;
this.paramInteger = paramInteger;
}
public void doSomething() {
System.out.println(this.paramInteger);
}
}
复制代码
由于匿名内部类最终用会编译成一个单独的类,而被该类使用的变量会以构造函数参数的形式传递给该类,例如:Integer paramInteger,若是变量 不定义成final的,paramInteger在匿名内部类被能够被修改,进而形成和外部的paramInteger不一致的问题,为了不这种不一致的状况,由于Java 规定匿名内部类只能访问final修饰的外部变量
静态方法与静态成员变量能够被继承,可是不能被重写。它对子类隐藏,所以静态方法也不能实现多态
进程和线程的主要差异在于它们是不一样的操做系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不一样执行路径。线程有本身的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,因此多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行而且又要共享某些变量的并发操做,只能用线程,不能用进程。
final 用于声明属性,方法和类, 分别表示属性不可变, 方法不可覆盖, 类不可继承.
finally 是异常处理语句结构的一部分,表示老是执行.
finalize 是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,能够覆盖此方法提供垃圾收集时的其余资源回收,例如关闭文件等. JVM不保证此方法总被调用.
Serializable是Java中的序列化接口,其使用起来简单但 是开销很大,序列化和反序列化过程须要大量I/O操做。而Parcelable是Android中的序列化方式,所以更适合用在Android平台上,它的缺点就是使用起来稍微麻烦 点,可是它的效率很高,这是Android推荐的序列化方式,所以咱们要首选Parcelable。Parcelable主要用在内存序列化上,经过Parcelable将对象序列化到存储设备 中或者将对象序列化后经过网络传输也都是能够的,可是这个过程会稍显复杂,所以在这两种状况下建议你们使用Serializable。
因人而异,请自行整理答案
Integer a = 2;
private void test() {
String s1 = a.toString(); //方式一
String s2 = Integer.toString(a); //方式二
String s3 = String.valueOf(a); //方式三
}
复制代码
方式一源码:
public String toString() {
return toString(value);
}
public static String toString(int i) {
if (i == Integer.MIN_VALUE)
return "-2147483648";
int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
char[] buf = new char[size];
getChars(i, size, buf);
return new String(buf, true);
}
复制代码
能够看出
方式一
最终调用的是方式二
经过toString()方法,能够把整数(包括0)转化为字符串,可是 Integer 若是是 null 的话,就会报空指针异常
方式三源码:
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
复制代码
能够看出 当 Integer 是null的时候,返回的String是 字符串 "null" 而不是 null