咦咦咦,各位小可爱,我是你们的好伙伴——bug菌,今天又来给大家普及Java SE相关知识点了,别躲起来啊,听我讲干货还不快点赞,赞多了我就有动力讲得更嗨啦!所以呀,养成先点赞后阅读的好习惯,别被干货淹没了哦~
🏆本文收录于 **[「滚雪球学Java」 ](https://blog.csdn.net/weixin_43970743/category_9600553.html)专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅**!持续更新中,up!up!up!!
环境说明:Windows 10 + IntelliJ IDEA 2021.3.2 + Jdk 1.8
在Java中,所有的对象都是从Object类继承而来的。因此,理解Object类的属性和方法,对于熟悉Java编程语言至关重要。本文将介绍Object类的基本属性和方法,并解释它们在Java编程中的作用。
本文以Java开发语言为例,详细介绍了Object类的基本属性和方法。其中,介绍了Object类的equals()方法、hashCode()方法和toString()方法的作用,以及如何重写它们以满足我们自己的需要。此外,还介绍了getClass()方法、wait()方法、notify()方法和notifyAll()方法的作用,在多线程编程中有重要的用途。
在Java中,所有的类都是从Object类继承而来的。因此,Object类是Java中所有类的父类。Object类中包含了一些基本的属性和方法,用于操作对象.
equals()方法用于比较两个对象是否相等。如果两个对象相等,即它们的引用指向同一个对象,或者它们的值相等,则equals()方法返回true,否则返回false。对于自定义的类,需要重写equals()方法以实现自定义的比较逻辑。
示例代码如下:
class Person {
private String name;
public Person(String name) {
this.name = name;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Person person = (Person) obj;
return name != null ? name.equals(person.name) : person.name == null;
}
@Override
public int hashCode() {
return name != null ? name.hashCode() : 0;
}
public String getName() {
return name;
}
}
public class TestEquals {
public static void main(String[] args) {
Person person1 = new Person("Alice");
Person person2 = new Person("Alice");
System.out.println("Equals Test: " + person1.equals(person2)); // 应该输出 true
}
}
代码解析:
根据如上案例代码,这里我给同学们做个解读:这段代码演示了如何为自定义类Person
重写equals()
和hashCode()
方法,并提供了一个测试案例来验证重写的效果。
类定义分析:
Person
类包含一个私有字段name
,用于存储人的名字。name
字段。equals()
方法被重写,以提供基于名字字段的相等性比较:this == obj
)。null
,或者是否与当前对象属于同一个类(getClass() != obj.getClass()
)。Person
类型,并比较name
字段。hashCode()
方法被重写,以提供基于名字字段的哈希码生成逻辑。如果name
不为空,则返回name
的哈希码,否则返回0。getName()
方法返回name
字段的值。测试案例分析:
TestEquals
类中的main
方法创建了两个Person
对象person1
和person2
,它们具有相同的name
值("Alice")。person1.equals(person2)
调用equals()
方法来比较这两个对象。由于equals()
方法是基于name
字段实现的,所以即使person1
和person2
不是同一个对象引用,它们也应该被认为是相等的。"Equals Test: true"
,表示两个Person
对象被认为是相等的。 这个测试案例演示了如何正确重写equals()
方法,以确保对象的相等性不仅仅基于内存地址,而是基于对象的属性值。同时,这也展示了如何编写测试代码来验证自定义类的equals()
方法是否按预期工作。
hashCode()方法返回对象的哈希码,用于将对象存储到哈希表中。如果两个对象相等,则它们的哈希码也必须相等。因此,对于自定义的类,需要重写hashCode()方法以保证哈希表中存储的对象是按照自定义的比较逻辑排列的。
示例代码如下:
import java.util.HashMap;
public class TestHashCode {
public static void main(String[] args) {
HashMap<Person, String> map = new HashMap<>();
Person person = new Person("Bob");
map.put(person, "Value");
Person samePerson = new Person("Bob");
System.out.println("HashCode Test: " + map.containsKey(samePerson)); // 应该输出 true
}
}
代码解析:
根据如上案例代码,这里我给同学们做个解读:这段Java代码演示了如何使用HashMap
来存储键值对,并尝试检查一个具有相同属性的新对象是否已经被存储在HashMap
中。
以下是代码的逐行解析:
import java.util.HashMap;
- 导入Java的HashMap
类,这是一个基于哈希表的映射接口实现。public class TestHashCode {
- 定义了一个名为TestHashCode
的公共类。public static void main(String[] args) {
- 定义了main
方法,它是Java程序的入口点。HashMap<Person, String> map = new HashMap<>();
- 创建了一个HashMap
实例,其键类型为Person
,值类型为String
。Person person = new Person("Bob");
- 创建了一个Person
对象,并通过构造函数初始化其名字属性为"Bob"。map.put(person, "Value");
- 将Person
对象作为键,字符串"Value"作为值,存入HashMap
。Person samePerson = new Person("Bob");
- 创建了另一个Person
对象,同样初始化其名字属性为"Bob"。System.out.println("HashCode Test: " + map.containsKey(samePerson));
- 尝试检查HashMap
是否包含键为samePerson
的条目。如果Person
类正确地重写了equals
和hashCode
方法,那么即使samePerson
是一个新的对象实例,它也应该与之前存储的Person
对象具有相同的属性,因此map.containsKey(samePerson)
应该返回true
。}
- 结束main
方法。}
- 结束TestHashCode
类。注意: 这段代码中Person
类没有给出定义。如果Person
类没有正确重写equals
和hashCode
方法,那么即使两个Person
对象具有相同的属性,map.containsKey(samePerson)
也可能返回false
,因为HashMap
会使用对象的hashCode
值来确定键的存储位置,而默认情况下,每个新对象的hashCode
值都是不同的。
为了使代码按预期工作,Person
类需要重写equals
方法来比较对象的属性,以及hashCode
方法来提供一致的哈希码。例如:
public class Person {
private String name;
public Person(String name) {
this.name = name;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return name != null ? name.equals(person.name) : person.name == null;
}
@Override
public int hashCode() {
return name != null ? name.hashCode() : 0;
}
}
这段额外的代码将确保Person
对象的equals
和hashCode
方法根据其name
属性正确工作。
toString()方法返回对象的字符串表示。默认情况下,toString()方法返回对象的类名和哈希码。对于自定义的类,需要重写toString()方法以返回自定义的字符串表示。
示例代码如下:
public class TestToString {
public static void main(String[] args) {
Person person = new Person("Charlie");
System.out.println("ToString Test: " + person); // 使用默认的toString实现
System.out.println("Custom ToString Test: " + person.toString()); // 使用自定义的toString实现
}
}
代码解析:
根据如上案例代码,这里我给同学们做个解读:这段Java代码演示了如何使用System.out.println
打印对象的字符串表示形式,包括使用默认的toString
实现和自定义的toString
实现。
以下是代码的逐行解析:
public class TestToString {
- 定义了一个名为TestToString
的公共类。public static void main(String[] args) {
- 定义了main
方法,它是Java程序的入口点。Person person = new Person("Charlie");
- 创建了一个Person
对象,并通过构造函数初始化其名字属性为"Charlie"。System.out.println("ToString Test: " + person);
- 使用System.out.println
打印字符串"ToString Test: "后跟person
对象的字符串表示。由于没有显示调用toString
方法,这里使用的是Person
类继承自Object
类的默认toString
实现,它通常返回对象的类名和哈希码的无符号十六进制表示。System.out.println("Custom ToString Test: " + person.toString());
- 首先调用person
对象的toString
方法,然后使用System.out.println
打印字符串"Custom ToString Test: "后跟toString
方法的返回值。这里假设Person
类重写了toString
方法,提供了自定义的字符串表示。}
- 结束main
方法。}
- 结束TestToString
类。注意: 这段代码中Person
类没有给出定义。如果Person
类没有重写toString
方法,那么第二行打印语句将调用Object
类的toString
方法,而不是Person
类的自定义实现。如果Person
类重写了toString
方法,那么第二行打印语句将显示自定义的字符串表示。
例如,如果Person
类重写了toString
方法,它可能看起来像这样:
public class Person {
private String name;
public Person(String name) {
this.name = name;
}
// 重写toString方法
@Override
public String toString() {
return "Person{name='" + name + "'}";
}
}
在这个例子中,Person
类的toString
方法返回一个格式化的字符串,其中包含了Person
对象的name
属性。这样,当调用person.toString()
时,它将返回如"Person{name='Charlie'}"
的字符串,而不是默认的类名和哈希码表示。
getClass()方法返回对象的类类型。在Java中,类也是一个对象,因此可以使用getClass()方法获取类的类类型。
示例代码如下:
public class TestGetClass {
public static void main(String[] args) {
Person person = new Person("David");
Class<?> cls = person.getClass();
System.out.println("GetClass Test: " + cls.getName()); // 输出 Person
}
}
代码解析:
根据如上案例代码,这里我给同学们做个解读:这段Java代码演示了如何使用getClass()
方法获取对象的Class
对象,并使用这个Class
对象来获取类名。
以下是代码的逐行解析:
public class TestGetClass {
- 定义了一个名为TestGetClass
的公共类。public static void main(String[] args) {
- 定义了main
方法,它是Java程序的入口点。Person person = new Person("David");
- 创建了一个Person
对象,并通过构造函数初始化其名字属性为"David"。Class<?> cls = person.getClass();
- 调用person
对象的getClass()
方法,获取其Class
对象,并将其赋值给cls
变量。这里的Class<?>
表示cls
是一个通配符类型,可以接受任何类型的Class
对象。System.out.println("GetClass Test: " + cls.getName());
- 使用System.out.println
打印字符串"GetClass Test: "后跟调用cls
的getName()
方法的结果。getName()
方法返回Class
对象所表示的类的全名,即Person
。}
- 结束main
方法。}
- 结束TestGetClass
类。注意: 这段代码中Person
类没有给出定义,但是它必须是一个有效的Java类。getClass()
方法是一个实例方法,它返回表示该实例的运行时类的对象。getName()
方法返回一个String
,表示调用它的类或接口的完全限定名称。
例如,如果Person
类定义如下:
public class Person {
private String name;
public Person(String name) {
this.name = name;
}
// 其他方法...
}
那么在TestGetClass
类中的main
方法执行时,person.getClass()
将返回Person
类的Class
对象,cls.getName()
将返回字符串"Person",最终控制台输出将是:
GetClass Test: Person
wait()方法、notify()方法和notifyAll()方法用于在多线程编程中实现线程间的协作。其中,wait()方法使线程进入等待状态,直到其它线程调用notify()方法或notifyAll()方法唤醒它;notify()方法和notifyAll()方法用于唤醒进入等待状态的线程。这三个方法只能在同步代码块中使用。
示例代码如下:
public class TestSynchronization {
private boolean ready = false;
public synchronized void prepare() {
while (!ready) {
try {
wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
public synchronized void start() {
ready = true;
notifyAll();
}
public static void main(String[] args) {
TestSynchronization test = new TestSynchronization();
Thread thread = new Thread(() -> {
test.prepare();
System.out.println("Ready!");
});
thread.start();
try {
Thread.sleep(1000); // 等待线程开始等待
} catch (InterruptedException e) {
e.printStackTrace();
}
test.start(); // 唤醒等待的线程
}
}
代码解析:
根据如上案例代码,这里我给同学们做个解读:这段Java代码演示了如何使用同步机制(synchronized)和等待/通知机制(wait/notify)来控制线程间的协作。以下是代码的逐行解析:
public class TestSynchronization {
- 定义了一个名为TestSynchronization
的公共类。private boolean ready = false;
- 在类中定义了一个私有成员变量ready
,初始值为false
,用来表示是否准备好开始执行。public synchronized void prepare() {
- 定义了一个名为prepare
的公共同步方法。synchronized
关键字确保同一时间只有一个线程可以执行这个方法。while (!ready) {
- 使用一个循环来检查ready
变量是否为false
。如果是,线程将等待。try {
- 开始一个try
块,用来捕获可能发生的InterruptedException
。wait();
- 调用当前线程的wait()
方法,导致线程等待,直到被另一个线程调用notifyAll()
唤醒。catch (InterruptedException e) {
- 捕获InterruptedException
异常,并在捕获后执行以下操作:Thread.currentThread().interrupt();
- 调用当前线程的interrupt()
方法,这将线程的中断状态设置为true
。}
- 结束catch
块。}
- 结束while
循环。public synchronized void start() {
- 定义了另一个名为start
的公共同步方法。ready = true;
- 将ready
变量设置为true
,表示现在可以开始执行。notifyAll();
- 调用当前对象的notifyAll()
方法,唤醒在此对象上等待的所有线程。public static void main(String[] args) {
- 定义了main
方法,它是Java程序的入口点。TestSynchronization test = new TestSynchronization();
- 创建了TestSynchronization
类的一个实例。Thread thread = new Thread(() -> {
- 创建了一个新的线程,其任务是执行一个匿名内部类,该类调用test.prepare()
方法。test.prepare();
- 在新线程中调用prepare
方法,使线程等待。System.out.println("Ready!");
- 当prepare
方法中的while
循环退出后,打印"Ready!"。});
- 结束匿名内部类的声明。thread.start();
- 启动新线程。try {
- 开始一个try
块,用来捕获Thread.sleep
可能抛出的InterruptedException
。Thread.sleep(1000);
- 使当前线程(即主线程)休眠1秒,以便让新线程有时间进入等待状态。}
- 结束try
块。catch (InterruptedException e) {
- 捕获InterruptedException
异常。e.printStackTrace();
- 如果发生异常,打印堆栈跟踪。}
- 结束catch
块。test.start();
- 在主线程中调用start
方法,设置ready
为true
并唤醒等待的线程。}
- 结束main
方法。}
- 结束TestSynchronization
类。代码执行流程:
TestSynchronization
对象和一个线程。prepare
方法,进入等待状态。start
方法,设置ready
为true
并唤醒新线程。这个例子展示了如何使用同步和等待/通知机制来控制线程的执行顺序。
除了继承Object类中的属性和方法之外,每个Java类都可以重写Object类中的方法,以实现自定义的逻辑。
在自定义的类中重写equals()方法时,需要遵循以下原则:
在重写equals()方法时,需要判断参数是否为null,是否是当前类的实例,以及是否满足自定义的比较逻辑。
在自定义的类中重写hashCode()方法时,需要保证相等的对象有相等的哈希码。通常情况下,可以根据对象的属性计算哈希码,并将它们相加得到最终的哈希码。
在自定义的类中重写toString()方法时,需要返回自定义的字符串表示。
在Java中,每个类都继承自Object类。这意味着,如果你创建了一个类,但没有显式地指定它的父类,那么它将自动继承Object类。
Object类是一个非常简单的类。它只有一个无参构造方法,没有成员变量,只有一些方法。以下是Object类的声明:
public class Object {
public Object() {}
public native int hashCode();
public boolean equals(Object obj) {
return (this == obj);
}
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 >= 500000 || (nanos != 0 && timeout == 0)) {
timeout++;
}
wait(timeout);
}
public final void wait() throws InterruptedException {
wait(0);
}
protected void finalize() throws Throwable { }
}
在上面的代码中,我们可以看到Object类的构造方法,hashCode(),equals(),clone(),toString()等方法。
Java Object类位于java.lang包中。有想法的同学可以仔细去研读下。
equals()方法是Object类中最重要的方法之一。它用于比较两个对象是否相等。以下是equals()方法的声明:
public boolean equals(Object obj)
如果两个对象相等,那么equals()方法应该返回true。如果它们不相等,应该返回false。如果你没有覆盖equals()方法,那么默认实现将使用==运算符来比较两个对象的引用地址。
在实现equals()方法时,需要遵循以下几个原则:
以下是一个实现equals()方法的例子:
package com.demo.javase.day42;
/**
* 实现equals()方法的例子
*
* @author bug菌
* @version 1.0
* @date 2023/10/12 15:09
*/
public class MyClassToEquals {
private int x;
private int y;
//重写equals()
public boolean equals(Object o) {
if (!(o instanceof MyClassToEquals)) { // 检查o是否是MyClassToEquals类型
return false;
}
MyClassToEquals obj = (MyClassToEquals) o; // 强制转换为MyClassToEquals类型
return obj.x == x && obj.y == y; // 比较x和y
}
}
在这个例子中,我们覆盖了equals()方法来比较MyClassToEquals对象的x和y变量。我们首先检查传入的对象是否是MyClassToEquals类型,然后将其转换为MyClassToEquals类型。最后,我们比较x和y的值。
而对equals()源码来看,实现方式是非常简单粗暴的,通常并不推荐使用,因为在实际应用中,我们需要比较的是对象的内容是否相等,而不是仅仅比较它们的引用地址。正确的实现方式需要比较对象的每个属性是否都相等,包括它们的类型、值等。
根据如上重写equals()方法后,我们可以进行示例测试。
测试代码如下:
package com.demo.javase.day42;
/**
* 实现equals()方法的例子
*
* @author bug菌
* @version 1.0
* @date 2023/10/12 15:09
*/
public class MyClassToEquals {
private int x;
private int y;
//重写equals()
public boolean equals(Object o) {
if (!(o instanceof MyClassToEquals)) { // 检查o是否是MyClassToEquals类型
return false;
}
MyClassToEquals obj = (MyClassToEquals) o; // 强制转换为MyClassToEquals类型
return obj.x == x && obj.y == y; // 比较x和y
}
public static void main(String[] args) {
MyClassToEquals myClassToEquals_1 = new MyClassToEquals();
MyClassToEquals myClassToEquals_2 = new MyClassToEquals();
myClassToEquals_1.x = 1;
myClassToEquals_1.y = 2;
myClassToEquals_2.x = 1;
myClassToEquals_2.y = 2;
System.out.println(myClassToEquals_1.equals(myClassToEquals_2));
}
}
测试结果如下:
hashCode()方法是Object类另一个重要的方法。它用于返回一个对象的哈希码。哈希码是一个整数,用于表示对象的状态。
在Java中,哈希码通常用于在散列表中查找对象。如果你不重新实现hashCode()方法,它将返回对象的默认哈希码,该哈希码是根据对象的内存地址计算得出的。所以,如果两个对象的引用地址不同,它们的哈希码也会不同。
为了正确地使用散列表,你需要重新实现hashCode()方法,并确保如果两个对象相等,它们的哈希码也相等。以下是hashCode()方法的声明:
public native int hashCode();
在重新实现hashCode()方法时,需要遵循以下原则:
以下是一个实现hashCode()方法的例子:
package com.demo.javase.day42;
/**
* 实现hashCode()方法的例子
*
* @author bug菌
* @version 1.0
* @date 2023/10/12 14:54
*/
public class MyClassToHashCode {
private int x;
private int y;
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}
}
在这个例子中,我们重写了hashCode()方法以返回基于x和y变量的哈希码。我们使用31作为质数来生成哈希码。这里的关键在于使用质数,可以减少哈希码冲突的可能性。
测试结果如下:
如果不重写hashCode()方法,则输出的是对象的默认哈希码,也就是对象在内存中的地址经过哈希算法处理后的值。演示截图如下:
toString()方法是Object类的另一个重要方法。它用于返回一个对象的字符串表示形式。该字符串通常包含对象的类型和一些有用的信息。
在Java中,toString()方法通常用于将对象转换为字符串。例如,如果你有一个Person类,你可以通过调用person.toString()来获取该Person对象的字符串表示形式。
以下是toString()方法的声明:
public String toString()
以下是一个实现toString()方法的例子:
package com.demo.javase.day42;
/**
* 实现toString()方法的例子
*
* @author bug菌
* @version 1.0
* @date 2023/10/12 14:55
*/
public class MyClassToString {
private int x;
private int y;
public String toString() {
return "MyClass [x=" + x + ", y=" + y + "]";
}
public static void main(String[] args) {
MyClassToString myClassToString = new MyClassToString();
myClassToString.x = 1;
myClassToString.y = 2;
System.out.println(myClassToString.toString());
}
}
在这个例子中,我们重写了toString()方法以返回一个包含x和y变量的字符串。这个字符串可以让我们更好地理解MyClass对象的状态。
测试结果如下:
如果对象没有重写 toString 方法,直接调用 toString 方法会输出对象的类名和内存地址的字符串表示。例如,一个没有重写 toString 方法的 Object 对象,调用 toString 方法会输出类似于以下形式的字符串:getClass().getName() + "@" + Integer.toHexString(hashCode())
。演示结果如下:
代码拓展:
如上段代码定义了一个名为MyClassToString
的类。这个类有两个私有的整型变量x
和y
,这里我给同学们解读下。
toString()
是Object
类的一个方法,所有的类都继承了Object
类,可以重写这个方法。在这段代码中,toString()
方法被重写了,返回一个字符串,其中包含了对象的属性x
和y
的值。
在main
方法中,创建了一个MyClassToString
的对象myClassToString
,并给x
和y
赋值为1
和2
。然后,通过调用toString()
方法,将对象转换为字符串,并打印输出。输出结果为MyClass [x=1, y=2]
。这段代码定义了一个名为MyClassToString
的类。这个类有两个私有的整型变量x
和y
。
toString()
是Object
类的一个方法,所有的类都继承了Object
类,可以重写这个方法。在这段代码中,toString()
方法被重写了,返回一个字符串,其中包含了对象的属性x
和y
的值。
在main
方法中,创建了一个MyClassToString
的对象myClassToString
,并给x
和y
赋值为1
和2
。然后,通过调用toString()
方法,将对象转换为字符串,并打印输出。输出结果为MyClass [x=1, y=2]
。
Java的Object
类作为类层级结构的根基,为所有Java类提供了一个共同的起点。它所定义的方法,虽然数量不多,但每一个都扮演着至关重要的角色。理解这些方法的工作原理和使用场景,对于深入掌握Java语言和进行高效编程至关重要。
equals()
**方法**:是判断对象等价性的标准。默认实现仅比较对象的内存地址,但通常我们需要根据对象的属性来比较。因此,合理重写此方法,以实现基于属性值的等价性判断,是面向对象编程中封装和抽象思想的体现。hashCode()
**方法**:与equals()
方法紧密相关,用于散列存储结构中快速定位对象。正确的实现能够保证在散列表等数据结构中,相等的对象具有相同的哈希码,从而提高查找效率。toString()
**方法**:提供了对象的字符串表示形式,这在日志记录、调试和展示对象信息时非常有用。重写此方法可以提供更为直观和信息丰富的对象描述。getClass()
**方法**:返回对象的Class
对象,这不仅可以用来获取类的类型信息,也是反射机制的基础。wait()
**、**notify()
**和**notifyAll()
**方法**:这三个方法是Java并发编程中的基础,通过它们可以实现线程间的协调和通信,是实现同步机制的关键。equals()
和hashCode()
方法时,必须确保两者的一致性,即如果两个对象通过equals()
方法比较结果为true
,则它们的hashCode()
值也必须相等。toString()
方法的重写应当提供足够的信息,以便于开发者理解对象的状态,但同时要注意信息的敏感性,避免泄露重要数据。wait()
、notify()
和notifyAll()
进行线程间通信时,必须在同步代码块中调用,并且要注意捕获和处理InterruptedException
异常。 通过对Object
类方法的深入理解,我们可以看到Java设计者对于对象基本行为的规范和约束。每个方法都有其特定的用途和适用场景。掌握这些方法的正确使用和重写,能够帮助我们写出更加严谨、高效的代码。在实际开发中,合理利用这些方法,可以提升代码的可读性、可维护性和性能。
Java作为一种成熟的编程语言,其核心类的设计充满了哲学和智慧。Object
类的方法虽然简单,但它们是构建复杂应用的基础。作为Java开发者,我们应当深入理解这些基础概念,并在实践中不断探索和应用,以达到更高的编程境界。
无论你是计算机专业的学生,还是对编程有兴趣的小伙伴,都建议直接毫无顾忌的学习此专栏「滚雪球学Java」,bug菌郑重承诺,凡是学习此专栏的同学,均能获取到所需的知识和技能,全网最快速入门Java编程,就像滚雪球一样,越滚越大,指数级提升。
码字不易,如果这篇文章对你有所帮助,帮忙给bug菌来个一键三连(关注、点赞、收藏) ,您的支持就是我坚持写作分享知识点传播技术的最大动力。 同时也推荐大家关注我的硬核公众号:「猿圈奇妙屋」 ;以第一手学习bug菌的首发干货,不仅能学习更多技术硬货,还可白嫖最新BAT大厂面试真题、4000G Pdf技术书籍、万份简历/PPT模板、技术文章Markdown文档等海量资料,你想要的我都有!
我是bug菌,CSDN | 掘金 | infoQ | 51CTO 等社区博客专家,历届博客之星Top30,掘金年度人气作者Top40,51CTO年度博主Top12,掘金等平台签约作者,华为云 | 阿里云| 腾讯云等社区优质创作者,全网粉丝合计30w+ ;硬核微信公众号「猿圈奇妙屋」,欢迎你的加入!免费白嫖最新BAT互联网公司面试题、4000G pdf电子书籍、简历模板等海量资料。
--End
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。