【Java基础】Java常用基础知识(二)

==和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
  1. 基本型和基本型封装型进行”==“运算符的比较,基本型封装型将会自动拆箱变为基本型后再进行比较,因此 Integer(0) 会自动拆箱为 int 类型再进行比较;
  2. 基本型封装类型调用equals(),但是参数是基本类型,这时候,先会进行自动装箱,基本型转换为其封装类型,再进行3中的比较。
  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语法规定。

接口与抽象类的区别

  1. 抽象类可以有构造方法(但不能直接通过new实例化,但可以通过子类继承,实例化子类),接口中不能有构造方法。
  2. 一个类可以实现多个接口,但只能继承一个抽象类。
  3. 抽象类中可以有普通成员变量,接口中没有普通成员变量。
  4. 抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static final类型。
  5. 抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的(public abstract),不能有非抽象的普通方法。
  6. (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的区别

  1. Cookie存储在客户端阅读器中,对客户端是可见的,客户端的一些程序可能会窥探、复制以至修正Cookie中的内容。而Session存储在服务器上,对客户端是透明的。
    在这里插入图片描述
  2. cookie 是在HTTP协议下,服务器或脚本可以维护客户工作站上信息的一种方式。cookie 是由 Web服务器保存在用户浏览器(客户端)上的小文本文件(内容通常经过加密),它可以包含有关用户的信息。无论何时用户链接到服务器,Web站点都可以访问cookie 信息,可以看作是浏览器缓存。
  3. 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 配置模式,以及动态代理模式都用到了反射。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值