先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
正文
protected native Object clone() throws CloneNotSupportedException;
public String toString() {
return getClass().getName() + “@” + Integer.toHexString(hashCode());
}
public final native void notify();
public final native void notifyAll();
public final native void wait(long timeout) throws InterruptedException;
public final void wait(long timeout, int nanos) throws InterruptedException {
if (timeout < 0) {
throw new IllegalArgumentException(“timeout value is negative”);
}
if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException(
“nanosecond timeout value out of range”);
}
if (nanos > 0) {
timeout++;
}
wait(timeout);
}
public final void wait() throws InterruptedException {
wait(0);
}
protected void finalize() throws Throwable { }
}
复制代码
1.getClass方法
public final native Class<?> getClass();
复制代码
返回此 Object 的运行时类,返回的类对象是被表示类的static synchronized方法锁定的对象。不可以重写,要调用的话,一般和getName()联合使用。
类加载的第一阶段就是将.class文件加载到内存,并生成一个java.lang.Class对象的过程。getClass()方法就是获取这个对象,这是当前类的对象在运行时类的所有信息的集合。这个方法也是三种反射方式之一。
反射三种方式:
-
对象的getClass();
-
类名.class;
-
Class.forName();
class extends ObjectTest {
private void privateTest(String str) {
System.out.println(str);
}
public void say(String str) {
System.out.println(str);
}
}
public class ObjectTest {
public static void main(String[] args) throws Exception {
ObjectTest = new ();
//获取对象运行的Class对象
Class<? extends ObjectTest> aClass = .getClass();
System.out.println(aClass);
//getDeclaredMethod这个方法可以获取所有的方法,包括私有方法
Method privateTest = aClass.getDeclaredMethod(“privateTest”, String.class);
//取消java访问修饰符限制。
privateTest.setAccessible(true);
privateTest.invoke(aClass.newInstance(), “private method test”);
//getMethod只能获取public方法
Method say = aClass.getMethod(“say”, String.class);
say.invoke(aClass.newInstance(), “Hello World”);
}
}
输出结果:
class test.
private method test
Hello World
复制代码
2.registerNatives方法
private static native void registerNatives();
static {
registerNatives();
}
复制代码
该方法中的静态代码块就是一个类在初始化过程中必定会执行的内容,所以在类加载的时候会执行该方法,通过该方法来注册绑定本地方法。通过以下OpenJDK中的Thread.c的部分代码
···
static JNINativeMethod methods[] = {
{“start0”, “()V”, (void *)&JVM_StartThread},
{“stop0”, “(” OBJ “)V”, (void *)&JVM_StopThread},
{“isAlive”, “()Z”, (void *)&JVM_IsThreadAlive},
{“suspend0”, “()V”, (void *)&JVM_SuspendThread},
{“resume0”, “()V”, (void *)&JVM_ResumeThread},
{“setPriority0”, “(I)V”, (void *)&JVM_SetThreadPriority},
{“yield”, “()V”, (void *)&JVM_Yield}
};
JNIEXPORT void JNICALL
Java_java_lang_Thread_registerNatives(JNIEnv *env, jclass cls)
{
(*env)->RegisterNatives(env, cls, methods, ARRAY_LENGTH(methods));
}
···
复制代码
通过以上代码可知registerNatives方法是通过JNI_onload函数实现动态绑定。
Object类中的registerNatives方法的作用深入介绍
3.clone方法
protected native Object clone() throws CloneNotSupportedException;
复制代码
该方法是保护方法,实现对象的浅复制,只有实现了Cloneable接口才可以调用该方法,否则抛出CloneNotSupoortedException异常。克隆的对象通常情况下满足以下三条规则:
-
x.clone()!= x,克隆出来的对象和原来的对象不是同一个,指向不同的内存地址
-
x.clone().getClass() == x.getClass()
-
x.clone().equals(x)
默认的clone方法是浅拷贝。所谓浅拷贝,指的是对象内属性引用的对象只会拷贝引用地址,而不会将引用的对象重新分配内存。而深拷贝则是会连引用的对象也重新创建。
以Employee为例,它里面有一个域hireDay不是基本数据类型的变量,而是一个reference变量,经过Clone之后就会产生一个新的Date型的reference,它和原始对象中对应的域指向同一个Date对象,这样克隆类就和原始类共享了一部分信息,而这样显然是不利的,过程下图所示:
这个时候我们就需要进行深拷贝了,对那些非基本型别的域进行特殊的处理,例如本例中的hireDay。我们可以重新定义Clone方法,对hireDay做特殊处理,如下代码所示:
class Employee implements Cloneable {
public Object clone() throws CloneNotSupportedException {
Employee cloned = (Employee) super.clone();
cloned.hireDay = (Date) hireDay.clone()
return cloned;
}
}
复制代码
4.toString方法
public String toString() {
return getClass().getName() + “@” + Integer.toHexString(hashCode());
}
复制代码
toString方法返回一个字符串,该方法中的getClass().getName()是返回对象的全类名(包含包名),Integer.toHexString()是将hash码以十六进制无符号整数形式返回此hash码的字符串表示形式。一般在子类中我们可以对这个方法进行重写。
5.equals方法(重要)
public boolean equals(Object obj) {
return (this == obj);
}
复制代码
equals方法用来直接判断this和obj本省的值是否相等,即用来判断调用equals的对象和形参obj所引用的对象是否同一对象,所谓同一对象就是指内存中同一块存储单元,如果this和obj指向的是同一块内存对象,则返回true,否则返回false。
注意事项:
-
即便是内容完全相等的两块不同的内存对象,也返回false。
-
如果希望不同内存但相同内容的两个对象时,Object中的equals方法返回true,则我们需要重写父类的equals方法。
-
String类已经重写了Object类的equals方法
String类重写Object类的equals方法
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是引用类型,比较时不能比较引用是否相等,重点是在于字符串的内容是否相等。
在Java规范中,对equals方法的使用必须遵循一下几个原则:
-
自反性:对于任何非空引用值x,x.equals(x)都应返回true。
-
对称性:对于任何非空引用值x和y,当且仅当 y.equals(x)返回true时,x.equals(y)才应返回true。
-
传递性:对于任何非空引用值x、y和z,如果x.equals(y)返回true,并且y.equals(z)返回true,那么x.equals(z)应返回true。
-
一致性:对于任何非空引用值x和y,多次调用x.equals(y)始终返回true或始终返回false,前提是对象上equals比较中所用的信息没有被修改。
-
对于任何非空引用值x,x.equals(null)都应返回false。
请注意,无论何时重写此方法,通常都必须重写hashCode方法,以维护hashCode方法的一般约定,该方法声明相等对象必须具有相同的哈希代码。
6.hashCode方法(重要)
public native int hashCode();
复制代码
hashCode方法用一个native来声明,返回该对象的哈希码,是int类型的数值,用于哈希查找,可以减少在查找中使用equals的次数。
哈希算法也称为散列算法,是将数据依特定算法产生的结果直接指定到一个地址上,整个结果是由hashCode()方法产生的。
这里有 A,B,C,D四个对象,分别通过hashCode方法产生了三个值,注意A和B对象调用hashCode产生的值是相同的,即A.hashCode()=B.hashCode()=0x001,发生了哈希冲突,这时候由于最先是插入了A,在插入的B的时候,我们发现B是要插入到A所在的位置,而A已经插入了,这时候就通过调用equals方法判断A和B是否相同,如果相同就不插入B,如果不同则将B插入到A后面的位置。
hashCode()要求:
-
在程序运行期间,只要对象的变化不影响equals方法的记过,那么无论调用多少次hashCode,都必须返回同样的hash码。
-
通过equals调用返回true的两个对象的hashCode一定相同。
-
通过equals返回false的两个对象的hashCode不需要不同,可以相同。
hashCode()结论:
-
若两个对象相等,其hash码一定相同。
-
若两个对象不相等,其hash码有可能相同。
-
若hash码相同的两个对象,不一定相等。
-
若hash码不相同的两个对象,一定不相等。
注意事项:
hash值是一个int类型(占用四个字节),要避免溢出,
不同的对象hash码应尽量不同,避免hash冲突,也就是算法获得的元素要尽量均匀分布。
对于Map集合,key最好选择基本数据类型和String类型,因为他们都按照规范重写了equals()方法和hashCode()方法。
String类型hashCode源码:
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
复制代码
hash集合实现原理:
最后
光给面试题不给答案不是我的风格。这里面的面试题也只是凤毛麟角,还有答案的话会极大的增加文章的篇幅,减少文章的可读性
Java面试宝典2021版
最常见Java面试题解析(2021最新版)
2021企业Java面试题精选
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
只是凤毛麟角,还有答案的话会极大的增加文章的篇幅,减少文章的可读性
Java面试宝典2021版
[外链图片转存中…(img-Q7m3RWFW-1713620420788)]
[外链图片转存中…(img-sBIeTn22-1713620420789)]
最常见Java面试题解析(2021最新版)
[外链图片转存中…(img-29J4qURY-1713620420789)]
[外链图片转存中…(img-m0pNf2Fg-1713620420790)]
2021企业Java面试题精选
[外链图片转存中…(img-j8UB157X-1713620420790)]
[外链图片转存中…(img-AB67pffl-1713620420791)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-CbheWHdA-1713620420791)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!