文章目录
- ==和equals的区别
- Integer
- 成员变量和局部变量和的区别
- 内部类(成员内部类、静态内部类、方法内部类)
- String 常量池与 JVM 字符串常量池的垃圾回收
- 重载和重写是什么?两者区别?
- 接口与抽象类的区别
- 深入理解HashMap和ConcurrentHashMap
- JVM初识理解与探究
- 类加载与双亲委派
- 常见的 IO 模型有哪些?Java 中的 BIO、NIO、AIO 有啥区别?
- 简单介绍session和cookie的区别
- 浏览器关闭后,Session就销毁了吗?(有助于了解websocket)
- rpc 和 http 有什么区别?
- spring事务和数据库事务的关系和相关知识总结(拓展:redis事务)
- 什么是反射?
==和equals的区别
- == 对比的是栈中的值,基本数据类型是变量值,引用类型是堆中内存对象的地址。
- equals:object 中默认也是采用 == 比较,可以重写,也通常会进行重写,不重写就和 == 没区别。
Object(默认)
public boolean equals(Object obj) {
return (this == obj);
}
String(进行重写)
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;
}
上述代码可以看出,String类中被复写的equals()方法其实是比较两个字符串的内容。
public class StringDemo {
public static void main(String args[]) {
String str1 = "Hello";
String str2 = new String("Hello");
String str3 = str2; // 引用传递
System.out.println(str1 == str2); // false
System.out.println(str1 == str3); // false
System.out.println(str2 == str3); // true
System.out.println(str1.equals(str2)); // true
System.out.println(str1.equals(str3)); // true
System.out.println(str2.equals(str3)); // true
}
}
在基本类型的包装类中,只要值相等,equals都是相等的,因为在基本类型的包装类中都对于equals进行重写。而其它没有重写equals()方法的类,比如我们自己定义的类,在使用equals()方法时,都是调用Object类的equals(),最终用"=="比较地址。
Integer
Integer的对象缓存机制
Integer 使用了对象缓存机制,默认缓存范围是-128~127区间的 Integer 实例。
在此区间内,推荐使用静态工厂方法 valueOf 或者直接声明获取对象实例,而不是 new,因为 valueOf 使用缓存,而 new 一定会创建新的对象分配新的空间,因为是新开创空间,即使是在这个范围内,也是不相等的。
Integer i = 100;
Integer j = Integer.valueOf(100);
Integer k = new Integer(100);
System.out.println(i == j); //true
System.out.println(i == k); //false
System.out.println(j == k); //false
阿里开发手册:所有的相同类型的包装类对象之间值的比较,全部使用 equals 方法比较。
说明:对于 Integer var = ?在-128至127之间的赋值,Integer 对象是在 IntegerCache.cache 产生,会复用已有对象,这个区间内 Integer 值可以直接使用 == 进行判断,但是这个区间之外的所有数据,都会在堆上产生,并不会复用已有对象,这是一个大坑,推荐使用 equals 方法进行判断。
参考:
https://www.cnblogs.com/rouqinglangzi/p/8848607.html
https://blog.csdn.net/yrwan95/article/details/82785129
自动拆装箱
int i = 0;
Integer j = new Integer(0);
System.out.println(i == j); //true
System.out.println(j.equals(i)); //true
- 基本型和基本型封装型进行”==“运算符的比较,基本型封装型将会自动拆箱变为基本型后再进行比较,因此 Integer(0) 会自动拆箱为 int 类型再进行比较;
- 基本型封装类型调用equals(),但是参数是基本类型,这时候,先会进行自动装箱,基本型转换为其封装类型,再进行3中的比较。
- 两个基本型的封装型进行 equals() 比较,首先 equals() 会比较类型,如果类型相同,则继续比较值,如果值也相同,返回 true。
成员变量和局部变量和的区别
成员变量(全局变量),可以分为实例变量和类变量(静态变量)
1、成员变量:定义在类中,方法体之外。变量在创建对象时实例化。成员变量可被类中的方法、构造方法以及特定类的语句块访问。示例如下:
public class ClassName{
int a;
public void printNumber(){ ... }
}
2、类变量:定义在类中,方法体之外,但必须要有 static 来声明变量类型。静态成员属于整个类,可通过对象名或类名来调用。
public class ClassName{
static int a;
public void printNumber(){ ... }
}
由static修饰的变量称为静态变量,其实质上就是一个全局变量。如果某个内容是被所有对象所共享,那么该内容就应该用静态修饰;没有被静态修饰的内容,其实是属于对象的特殊描述。
不同的对象的实例变量将被分配不同的内存空间, 如果类中的成员变量有类变量,那么所有对象的这个类变量都分配给相同的一处内存,改变其中一个对象的这个类变量会影响其他对象的这个类变量,也就是说对象共享类变量。
局部变量
… …
成员变量和局部变量的区别
成员变量:
①成员变量定义在类中,在整个类中都可以被访问。
②成员变量随着对象的建立而建立,随着对象的消失而消失,存在于对象所在的堆内存中。
③成员变量有默认初始化值。
局部变量:
①局部变量只定义在局部范围内,如:函数内,语句内等,只在所属的区域有效。
②局部变量存在于栈内存中,作用的范围结束,变量空间会自动释放。
③局部变量没有默认初始化值
其他详见:
https://blog.csdn.net/haovip123/article/details/43883109
https://blog.csdn.net/du_minchao/article/details/48881637
内部类(成员内部类、静态内部类、方法内部类)
https://blog.csdn.net/liu771626413/article/details/80577684
关联:Java中的static、final、abstract含义及使用方法
String 常量池与 JVM 字符串常量池的垃圾回收
https://blog.csdn.net/weixin_46286156/article/details/121905988
重载和重写是什么?两者区别?
重载: 发生在同一个类中,方法名必须相同,参数类型不同、个数不同、顺序不同,方法返回值和访问修饰符可以不同 ,发生在编译时。
注意:
不能通过返回类型区分重载。为什么函数重载不可以根据返回类型区分? 因为调用时不能指定类型信息,编译器不知道你要调用哪个函数。
例如:
float max(int a, int b);
int max(int a, int b);
当调用max(1,2);时无法确定调用的是哪个,单从这一点上来说,仅返回值类型不同的重载是不应该允许的。详见:https://www.zhihu.com/question/21455159/answer/59874307
重写: 发生在父子类中,方法名、参数列表必须相同,返回值范围小于等于父类,抛出的异常范围小于等于父类,访问修饰符范围大于等于父类;如果父类方法访问修饰符为private则子类就不能重写该方法。
PS:构造方法不能重写,但可以重载
说法一:被重写的前提是被继承,而构造方法根本就不能被继承,所以谈不上被重写。 所谓继承是:对于类与类而言的,而覆盖是对方法而言的
我们知道子类覆盖父类的方法需要两者的方法完全一致(权限修饰符除外),而且子类方法的权限要高于父类方法的权限;
因此我们知道,子类和父类的类名不通,构造方法就不存在着所谓的覆盖复写,我们只能在子类中调用父类的构造方法来初始化,也必须调用父类的构造函数进行初始化。
说法二:构造方法不是方法,其不能被static和final修饰,没有返回值和void值,所以构造方法只能重载不能重写。因重写的方法没有返回值和void值不符合Java语法规定。
接口与抽象类的区别
- 抽象类可以有构造方法(但不能直接通过new实例化,但可以通过子类继承,实例化子类),接口中不能有构造方法。
- 一个类可以实现多个接口,但只能继承一个抽象类。
- 抽象类中可以有普通成员变量,接口中没有普通成员变量。
- 抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static final类型。
- 抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的(public abstract),不能有非抽象的普通方法。
- (1)在JDK1.8之前的版本,接口不能有静态方法,抽象类中因为有普通方法,故也可以有静态方法。
(2)在JDK1.8和1.8后接口中也可以定义静态方法了(static修饰),而且也还可以定义默认(default)和私有方法(private)
使用场景:当你关注一个事物的本质的时候,用抽象类;当你关注一个操作的时候,用接口。
深入理解HashMap和ConcurrentHashMap
https://blog.csdn.net/weixin_46286156/article/details/121045955
JVM初识理解与探究
https://blog.csdn.net/weixin_46286156/article/details/121916206
类加载与双亲委派
https://blog.csdn.net/weixin_46286156/article/details/120944659
常见的 IO 模型有哪些?Java 中的 BIO、NIO、AIO 有啥区别?
https://snailclimb.gitee.io/javaguide/#/docs/java/basis/io
简单介绍session和cookie的区别
- Cookie存储在客户端阅读器中,对客户端是可见的,客户端的一些程序可能会窥探、复制以至修正Cookie中的内容。而Session存储在服务器上,对客户端是透明的。
- cookie 是在HTTP协议下,服务器或脚本可以维护客户工作站上信息的一种方式。cookie 是由 Web服务器保存在用户浏览器(客户端)上的小文本文件(内容通常经过加密),它可以包含有关用户的信息。无论何时用户链接到服务器,Web站点都可以访问cookie 信息,可以看作是浏览器缓存。
- session的作用是实现网页之间数据传递,是一个存储在服务器端的对象集合。它具有极高的简便性、可扩展性和可用性,也可以通过加密和SSL技术来提高其安全性。它是一种服务器端的机制,服务器使用一种类似于散列表的结构来保存信息。
详细介绍:https://www.cnblogs.com/l199616j/p/11195667.html
浏览器关闭后,Session就销毁了吗?(有助于了解websocket)
https://blog.csdn.net/MaNong125/article/details/122342484
rpc 和 http 有什么区别?
rpc就是远程调用,旨在方便服务与服务之间的通信而提出的一个概念。而http只不过是实现这个rpc概念的其中一种手段。就类似于一个是接口,一个是实现类。http确实可以拿来当做rpc来用,但是rpc并不只有http一个实现方案,如feign也是一种,当然也可以你自定义实现方案。
详细介绍:https://www.bilibili.com/video/BV1ki4y1D7Nf
https://www.bilibili.com/video/BV1Qv4y127B4
spring事务和数据库事务的关系和相关知识总结(拓展:redis事务)
https://blog.csdn.net/weixin_46286156/article/details/126899933
什么是反射?
反射就是在程序运行期间动态获取对象的属性和方法。它能够在程序运行期间,对于任意一个类,都能知道它所有的方法和属性。
获取 Class 对象的三种方式:getClass()、.class、Class.forName(“”)。
反射的优缺点:优点:运行期间能够动态获取类,代码的灵活性高。缺点:性能比直接的Java代码要低很多,相对来说不安全,破坏了类的封装性。
应用场景:spring 的 xml 配置模式,以及动态代理模式都用到了反射。