常用API
什么是API
看一个类
1.类所在的包
2.类的介绍,看是否能被继承
3.使用类-》创建他-》看他的构造方法
4.类的方法(1.返回值 2.参数 3.是不是静态方法,知道调用方式)
该板块展示继承自父类的方法
5.再详细看可以看父类
Object类
概述
Java中的Object类是所有类的根类,每个Java类都直接或间接地继承自Object类。
这使得Object类的实例方法可以被所有Java对象使用,因此它在Java编程中起着至关重要的作用。以下是关于Java中Object类的详细知识点:
一、Object类的基本介绍
- 定义:Object类是Java中所有类的超类(或称为父类、基类)。即使一个类没有显式地继承任何其他类,Java也会隐式地使其继承自Object类。
- 作用:提供了通用的方法,用于处理对象的基本操作,如比较、克隆、转换为字符串等。
二、Object类的常用方法
- 构造方法:
- Object类有一个默认的构造方法,子类可以调用父类的构造方法(如果子类有自己的构造方法,并且没有显式地调用父类的构造方法,则会自动调用父类的无参构造方法)。
- equals(Object obj):
- 用于比较两个对象是否相等。默认情况下,equals方法通过比较两个对象的内存地址来判断它们是否相等。但在实际应用中,子类通常会重写这个方法,以比较对象的内容是否相等。
- 注意:equals方法只能用于比较引用类型变量,且通常与hashCode方法一起重写,以维护hashCode方法的一般约定。
- hashCode():
- 返回对象的哈希码值。这个值是根据对象的内部地址或内容计算得到的,主要用于哈希表中确定对象的存储位置。
- 当equals方法被重写时,hashCode方法也应该被重写,以确保两个相等的对象具有相同的哈希码值。
- toString():
- 返回对象的字符串表示。默认情况下,toString方法返回类名加上“@”符号和对象的哈希码的无符号十六进制表示。子类通常会重写这个方法,以返回对象的实际内容或描述。
- clone():
- 用于创建并返回调用该方法的对象的一个副本。但是,clone方法是protected的,因此它只能在类的内部或其子类中被调用。要实现克隆功能,类必须实现Cloneable接口,并覆盖clone方法。
- 注意:clone方法提供的是浅克隆(Shallow Clone),如果对象包含其他对象的引用,则这些引用指向的对象不会被克隆。要实现深克隆(Deep Clone),需要自定义克隆逻辑或使用序列化机制。
- getClass():
- 返回对象的运行时类。这个方法返回的是Class类型的对象,它包含了与对象所属类有关的信息。
- wait()、notify()、notifyAll():
- 这些方法用于线程之间的通信。wait方法使当前线程等待,直到另一个线程调用该对象的notify()或notifyAll()方法。notify()方法唤醒在该对象监视器上等待的单个线程,而notifyAll()方法唤醒所有等待的线程。
三、使用原则与注意事项
- 当使用equals方法时,应确保它满足自反性、对称性、传递性、一致性和对于非空引用与null的比较返回false等特性。
- 在重写equals方法时,通常也需要重写hashCode方法,以保持hashCode方法的一般约定。
- clone方法默认提供浅克隆,如果需要深克隆,需要自定义克隆逻辑或使用序列化机制。
- wait()、notify()和notifyAll()方法应与synchronized关键字一起使用,以确保线程之间的正确同步。
四、总结
Object类是Java中所有类的根类,提供了基本的对象操作方法。了解并熟练掌握Object类的常用方法对于编写高质量的Java代码至关重要。在实际开发中,应根据需要重写equals、hashCode和toString等方法,以提供更有意义的对象比较和描述。同时,也应注意线程之间的通信和同步问题,确保程序的正确性和稳定性。
String类
Java中的String类是一个非常重要的类,用于表示和操作字符串。以下是关于String类的一些主要知识点:
一、String类的基本特性
- 不可变性:String对象是不可变的,即一旦创建了一个String对象,就不能改变其内容。每次对String对象的修改,实际上都是创建了一个新的String对象。
- final类:String类被声明为final,这意味着它不能被继承。
- 实现接口:String类实现了Serializable接口和Comparable接口,因此它支持序列化和比较操作。
二、String类的构造方法
- 直接赋值:通过双引号直接赋值给String变量,如
String str = "hello";
。这种方式会在字符串常量池中查找或创建字符串对象。 - 使用new关键字:通过
new
关键字创建String对象,String str = new String("hello");
。这种方式会在堆内存中创建新的String对象,并且还会在字符串常量池中查找或创建字符串对象(对于字符串字面量部分)。 - 其他构造方法:String类还提供了其他构造方法,如从字符数组、字节数组等创建String对象。
三、String类的常用方法
- 字符串长度:
length()
方法返回字符串的长度。 - 字符访问:
charAt(int index)
方法返回指定索引处的字符。 - 字符串比较:
equals(Object anObject)
:比较字符串内容是否相等。compareTo(String anotherString)
:按字典顺序比较两个字符串。compareToIgnoreCase(String str)
:按字典顺序比较两个字符串,不考虑大小写。
- 字符串连接:
concat(String str)
:将指定字符串连接到此字符串的结尾。- 使用
+
操作符进行连接。
- 字符串截取:
substring(int beginIndex, int endIndex)
方法返回字符串的一个子字符串。 - 字符串查找:
indexOf(int ch)
:返回指定字符在此字符串中第一次出现处的索引。lastIndexOf(int ch)
:返回指定字符在此字符串中最后一次出现处的索引。
- 字符串替换:
replace(char oldChar, char newChar)
:用新字符替换旧字符。replaceAll(String regex, String replacement)
:使用给定的替换字符串替换所有匹配给定正则表达式的子字符串。
- 字符串大小写转换:
toLowerCase()
:将字符串转换为小写。toUpperCase()
:将字符串转换为大写。
- 字符串拆分:
split(String regex)
方法根据匹配给定的正则表达式来拆分字符串。
四、字符串常量池
字符串常量池是Java堆内存中的一个特殊存储区域,用于存储字符串常量。当使用直接赋值方式创建String对象时,JVM会首先检查字符串常量池中是否存在相同内容的字符串对象,如果存在则直接返回该对象的引用,否则在字符串常量池中创建一个新的字符串对象并返回其引用。这种方式可以减少内存的开销,并提高程序的性能。
五、StringBuffer和StringBuilder
虽然String类提供了丰富的字符串操作方法,但由于其不可变性的特性,在需要对字符串进行频繁修改时,使用String类可能会导致大量的对象创建和销毁,从而影响性能。
为了解决这个问题,Java提供了StringBuffer和StringBuilder两个类,它们都是可变的字符序列,并且提供了丰富的字符串操作方法。其中,StringBuffer是线程安全的,而StringBuilder则不是线程安全的,因此在单线程环境下使用StringBuilder可以获得更好的性能。
六、字符串与基本数据类型的转换
Java提供了将字符串与基本数据类型(如int、double等)进行相互转换的方法。例如,可以使用Integer.parseInt(String s)
将字符串转换为int类型,使用String.valueOf(int i)
将int类型转换为字符串。
七、字符串编码与解码
在Java中,可以使用getBytes()
方法将字符串编码为字节序列,使用String(byte[] bytes, String charsetName)
构造方法将字节序列解码为字符串。在编码和解码时,需要指定字符集(如UTF-8、GBK等),以确保字符的正确表示。
以上是Java中String类的一些主要知识点,涵盖了String类的基本特性、构造方法、常用方法、字符串常量池、StringBuffer和StringBuilder、字符串与基本数据类型的转换以及字符串编码与解码等方面。
在Java中,finalize()
方法是 Object
类的一个方法,它在垃圾收集器决定销毁对象之前被调用。它的主要目的是让对象在被销毁前执行清理资源的操作,比如关闭文件、释放网络连接等。但需要注意的是,从Java 9开始,finalize()
方法已经被标记为过时(deprecated),因为现代垃圾收集器更加高效,且依赖 finalize()
方法进行资源清理可能会导致资源泄露和性能问题。因此,推荐使用 try-with-resources
语句、java.lang.ref.Cleaner
或显式的关闭/释放资源的方法来管理资源。
尽管如此,了解 finalize()
方法的用法对于理解Java的垃圾收集机制以及旧代码的维护仍然是有帮助的。
finalize() 方法的基本用法
finalize()
方法在 Object
类中被定义为受保护的(protected),因此你可以在你的类中覆盖(override)这个方法来自定义清理逻辑。但请注意,你不能改变 finalize()
方法的访问修饰符。
示例
下面是一个简单的示例,展示了如何覆盖 finalize()
方法:
public class TestFinalize { | |
@Override | |
protected void finalize() throws Throwable { | |
// 调用父类的 finalize 方法 | |
super.finalize(); | |
// 在这里执行清理资源的操作 | |
System.out.println("对象被垃圾收集器回收前,执行清理操作"); | |
} | |
public static void main(String[] args) { | |
TestFinalize obj = new TestFinalize(); | |
// 注意:仅当垃圾收集器决定回收 obj 时,finalize() 方法才会被调用 | |
// 我们不能直接控制 finalize() 方法的调用时机 | |
// 显式地让 obj 失去引用,增加垃圾收集器回收它的可能性 | |
obj = null; | |
// 尝试触发垃圾收集(注意:这并不能保证 finalize() 会被调用) | |
System.gc(); | |
// 提醒:不要依赖 finalize() 方法来释放资源,因为它是不确定的 | |
} | |
} |
注意事项
-
不要依赖
finalize()
方法来释放资源:如上所述,从Java 9开始,finalize()
方法已经被标记为过时。即使在使用早期版本的Java时,也不应依赖finalize()
方法来释放资源,因为它的调用时机是不确定的。 -
finalize()
方法只会被调用一次:如果对象在finalize()
方法执行期间重新变得可达(即,有引用指向了它),那么它的finalize()
方法将不会被再次调用。 -
性能问题:使用
finalize()
方法可能会影响垃圾收集器的性能,因为它增加了垃圾收集过程的复杂性。 -
替代方案:使用
try-with-resources
语句、java.lang.ref.Cleaner
类或显式的关闭/释放资源的方法来管理资源。
getClass()
方法
Java 中的一个方法,它属于 Object
类,因此所有的 Java 对象都继承了这个方法。getClass()
方法的作用是返回调用它的对象的运行时类(Class
类型的对象)。这个返回的 Class
对象包含了关于该对象所属类的信息,比如类的名称、父类、实现的接口、方法、构造函数等。
使用场景
-
反射(Reflection):
getClass()
方法常用于反射机制中,通过它可以动态地获取对象的类型信息,进而可以动态地调用对象的任何方法或访问对象的任何属性,而无需在编写代码时明确知道这些方法和属性的存在。 -
类型判断:可以使用
getClass()
方法与==
或equals()
方法一起进行类型判断,虽然通常推荐使用instanceof
关键字进行类型判断,但在某些特定情况下,直接比较类的Class
对象可能更为直接或有用。 -
创建对象的实例:通过
Class
对象的newInstance()
方法(注意:在 Java 9 及更高版本中,newInstance()
方法已被标记为过时,建议使用Class
的getDeclaredConstructor()
和Constructor
的newInstance()
方法代替),可以动态地创建类的实例。
示例代码
public class TestGetClass { | |
public static void main(String[] args) { | |
String str = "Hello, World!"; | |
Class<?> clazz = str.getClass(); | |
System.out.println("The class of str is: " + clazz.getName()); | |
// 使用反射调用toString方法 | |
try { | |
Method toStringMethod = clazz.getMethod("toString"); | |
String result = (String) toStringMethod.invoke(str); | |
System.out.println("The result of toString() is: " + result); | |
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { | |
e.printStackTrace(); | |
} | |
} | |
} |
这段代码首先通过 getClass()
方法获取 str
对象的 Class
对象,然后打印出这个类的名称。接着,它使用反射机制调用 str
对象的 toString()
方法,并打印出方法的返回值。
注意事项
- 在使用反射时,需要处理
NoSuchMethodException
、IllegalAccessException
和InvocationTargetException
等异常。 Class
对象的newInstance()
方法在 Java 9 及更高版本中已被标记为过时,推荐使用Class
的getDeclaredConstructor()
和Constructor
的newInstance()
方法来创建对象实例。- 类型判断时,通常推荐使用
instanceof
关键字,因为它既简单又安全。
hashCode
方法
(自我理解:基于什么属性来生成哈希码,那么对象之间的区别就基于这些生成哈希码的属性,如果对比两个属性之间的这些属性相同,那么他们具有相同的哈希码;)
是 Java 中的一个非常重要的概念,它主要用于基于哈希表的集合类(如 HashSet
、HashMap
、HashTable
等)中,以提高数据检索的效率。hashCode
方法是 Object
类中的一个方法,Java 中的每个类都继承自 Object
类,因此每个对象都可以调用 hashCode()
方法来获取其哈希码。
哈希码的作用
-
唯一性(相对):理想情况下,不同的对象应该产生不同的哈希码,以提高哈希表的性能。但在实际中,由于哈希码是整数,其值域有限(
int
类型的范围),因此不可能保证所有不同的对象都有唯一的哈希码。通常,我们希望尽可能减少哈希冲突(即不同对象产生相同哈希码的情况)。 -
性能:在哈希表中,对象的哈希码用于确定对象在哈希表中的存储位置(即桶的索引)。通过减少哈希冲突,可以提高哈希表的查找、插入和删除操作的效率。
自定义 hashCode
方法
当你创建自己的类,并且这个类的对象将被用作哈希表的键时,你应该重写 hashCode
方法。根据 Java 的规范,当你重写 hashCode
方法时,你还应该重写 equals
方法,以保持 hashCode
方法的常规协定,即相等的对象必须具有相等的哈希码。
hashCode
方法的常规协定
- 在 Java 应用程序执行期间,只要对象的 equals 比较中所用的信息没有被修改,那么对该对象多次调用
hashCode
方法必须始终如一地返回同一个整数。 - 如果两个对象根据
equals(Object)
方法是相等的,那么调用这两个对象中任一对象的hashCode
方法都必须产生相同的整数结果。 - 如果两个对象根据
equals(Object)
方法是不相等的,那么调用这两个对象中任一个对象的hashCode
方法,不要求一定产生不同的整数结果。但是,程序员应该意识到,为不相等的对象产生不同整数结果可以提高哈希表的性能。
示例
假设你有一个 Person
类,包含 name
和 age
两个属性,并希望将其实例用作哈希表的键。你应该这样重写 hashCode
和 equals
方法:
public class Person { | |
private String name; | |
private int age; | |
// 构造函数、getter 和 setter 省略 | |
@Override | |
public boolean equals(Object obj) { | |
if (this == obj) return true; | |
if (obj == null || getClass() != obj.getClass()) return false; | |
Person person = (Person) obj; | |
return age == person.age && | |
Objects.equals(name, person.name); | |
} | |
@Override | |
public int hashCode() { | |
return Objects.hash(name, age); // 使用 Objects 类的 hash 方法来生成哈希码 | |
// 或者手动实现,例如:return name.hashCode() * 31 + age; | |
} | |
} |
在这个例子中,hashCode
方法使用了 Objects.hash
方法来生成基于 name
和 age
的哈希码。你也可以选择自己实现哈希码的计算逻辑,但关键是要确保相等的对象产生相同的哈希码。