常用类1
①.内部类
内部类的分类
- 成员内部类:将一个类定义在另外一个类当中作为它的成员
- 静态内部类:在类的前面有static关键字修饰的类
- 局部内部类:定义在方法内部的类
- 匿名内部类:没有名字的内部类,在接口等的使用中较多
概念:内部类就是在一个类的内部再定义一个完整的类。二者是包含关系
特点:
- 编译后能够生成独立的.class文件
- 内部类可以直接访问外部类的私有成员,而不会破坏封装
- 内部类可以为外部类提供必要的内部组件
public class InClass {
private int id;
//内部类
class outPut{
void show(){
//内部类能够直接访问外部类的私有成员,且不会破坏封装
System.out.println(id);
}
}
public static void main(String[] args) {
InClass inClass = new InClass();
outPut out = inClass.new outPut();
//内部类可以提供必要的内部功能组件
out.show();
}
}
-成员内部类
- 在类的内部定义,与实例变量(属性)、实例方法是同级别的类。
- 成员内部类是外部类的一个实例部分,创建内部类对象时,要依赖外部类对象。(要先创建外部类对象,再获取内部类)
- 当外部类与内部类有相同的属性时,优先使用成员内部类的属性。
这时需要 OuterName.this.XXX,才能访问外部类属性- 成员内部类当中不能定义静态成员(属性)!
但是能够包含静态变量
public class Outer{
//外部类的实例变量(属性)
private int id = 1122;
private String name = "iFinder";
//外部类的实例方法
public void outID(){
System.out.println("Outer ID " + id);
}
class Inner{
//成员内部类的属性
private String name = "in iFinder";
public void show(){
System.out.println("Inner name " + this.name); //访问的是内部类的属性
System.out.println("Outer name " + Outer.this.name); //访问的是外部类的属性
}
}
public static void main(String[] args) {
//1.获取外部类实例
Outer outer = new Outer();
//2.获取内部类实例
Inner inner = outer.new Inner();
//3.调用内部类的方法
inner.show();
//4.简化表达
Inner inner1 = new Outer().new Inner();
//先创建外部类对象才能获取内部类对象
}
}
-静态内部类
static关键字修饰的类
- 不依赖外部类对象,可以直接创建或通过类名访问的类。
静态内部类可以声明静态成员(属性)。
public class StaticClassTest {
private int id = 18;
private String name = "iFinder";
//静态内部类,级别与外部类相同
//所以调用外部类的属性与方法的时候也需要像其它外部的类一样,先获取外部类的实例对象
static class Inner{
private static double PI = 3.1415926;
void show(){
//获取外部类的对象
StaticClassTest test = new StaticClassTest();
//调用外部类的属性
System.out.println(test.id);
System.out.println(test.name);
//调用内部类的属性
System.out.println(this.PI);
}
}
public static void main(String[] args) {
//获取静态内部类的实例对象
StaticClassTest.Inner inner = new StaticClassTest.Inner();
//调用静态内部类的方法
inner.show();
}
}
-局部内部类
- 定义再外部类的方法当中,作用范围和创建对象仅限于当前的方法。
- 局部内部类访问外部类当前方法中的局部变量时,无法保证变量的声明周期与自身相同,变量的修饰符必须为final
- 局部内部类只能在当前的方法中使用
public class PartClass {
private String name = "iFinder";
public void show(){
//定义局部变量
int count = 0;
//局部内部类
//和局部变量一样,不能加private,static等访问修饰符
class PartInner{
private String phone = "13455671328";
private String email = "ifinder@163.com";
public void call(){
//访问外部类的属性
System.out.println(PartClass.this.name);
//访问内部类的属性
System.out.println(phone);
System.out.println(email);
//访问局部变量
//再jdk1.7前需要该变量为常量,但是在jdk1.8之后,Java会自动添加final关键字
System.out.println(count);
}
}
//在这里获取局部内部类的实例并调用方法,局部内部类的方法才能被调用
PartInner inner = new PartInner();
inner.call();
}
public static void main(String[] args) {
PartClass partClass = new PartClass();
partClass.show();
}
}
-匿名内部类
- 没有类名的局部内部类(一切特征都与局部内部类相同)
- 一般用在接口或者父类当中,必须继承一个父类或者实现一个接口
- 它是定义类、实现类、创建对象的语法的合并,它只能创建一个该类的对象。
- 优点:减少了代码量
- 缺点:可读性较差。
public class NoneNameClass {
public static void main(String[] args) {
//3.创建一个接口类型的对象
Usb mouse = new Mouse();
mouse.service();
// //通过局部内部类实现接口
// class Keyboard implements Usb{
//
// @Override
// public void service() {
// System.out.println("连接电脑成功,键盘开始工作!");
// }
// }
// //创建键盘的实例对象
// Usb keyboard = new Keyboard();
// keyboard.service();
//4.↑优化写法(内部类只使用一次,之后就再也不用了)
//相当于创建了一个局部内部类
Usb keyboard = new Usb() {
@Override
public void service() {
System.out.println("连接电脑成功,键盘开始工作!");
}
};
keyboard.service();
//5.Lambda表达式简化写法(针对函数表达式)
Usb fan = () -> System.out.println("连接电脑成功,风扇开始工作!");
fan.service();
}
}
//1.定义一个接口
interface Usb{
//定义接口内的一个方法
void service();
}
//2.创建一个类来实现Usb接口
class Mouse implements Usb{
//重写Usb中的方法
@Override
public void service() {
System.out.println("连接电脑成功,鼠标开始工作!");
}
}
②.Object类
- Object类:超类、基类,它是所有类的直接或间接父类,位于继承树的顶层。位于java.lang包中
- 任何类,如果没有extends关键字显示继承某个类,都会默认继承Object类,否则为间接继承。
- Object类中定义的方法,是所有对象都具备的方法。
- Object类型可以存储任何对象:
作为参数,可以接受任何对象。
作为返回值,可以返回任何对象。
-getClass()方法
public final Class<> getClass( ){ }
返回引用存储的实际对象的类型
应用:通常用于判断两个引用中实际存储的对象类型是否一致。
public class getClassTest {
public static void main(String[] args) {
Student s1 = new Student("iFinder",18);
Student s2 = new Student("Bobjoy",20);
//判断s1与s2是不是同一个类型
Class cls1 = s1.getClass();
Class cls2 = s2.getClass();
if (cls1 == cls2) System.out.println("s1与s2属于同一个类型");
else System.out.println("s1与s2不属于同一个类型");
}
}
class Student{
private String name;
private int age;
//构造器
public Student(String name, int age) {
this.name = name;
this.age = age;
}
//JavaBean
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
-hashCode( )方法
- public int hashCode( ) { }
- 返回对象的哈希码值
- 哈希值根据对象的地址或字符串或数字使用hash算法计算出来的int类型的数值
- 一般情况下,相同的对象会返回相同的哈希码
public class hashCodeTest {
public static void main(String[] args) {
Student1 s1 = new Student1("iFinder",18);
Student1 s2 = new Student1("Bobjoy",20);
//输出s1与s2的hashCode
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
//相同对象的hashCode相同
Student1 s3 = s1;
System.out.println(s3.hashCode());
}
}
class Student1{
private String name;
private int age;
//构造器
public Student1(String name, int age) {
this.name = name;
this.age = age;
}
//JavaBean
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
-toString方法
- public String toString( ) { }
- 返回该对象的字符串表示(表现形式)
- 可根据程序的需求重写该方法,如:展示对象的各个属性值
public class toStringTest {
public static void main(String[] args) {
Student2 s1 = new Student2("iFinder",18);
Student2 s2 = new Student2("Bobjoy",20);
//使用toString方法输出s1与s2对象
//System.out.println(s1.toString()); //输出:com.classtest.Student2@49e4cb85 完整包名+16进制hashCode
//System.out.println(s2.toString()); //输出:com.classtest.Student2@2133c8f8 完整包名+16进制hashCode
//不满足程序需求是可以对toString方法进行重写
System.out.println(s1.toString());
System.out.println(s2.toString());
}
}
class Student2{
private String name;
private int age;
//构造器
public Student2(String name, int age) {
this.name = name;
this.age = age;
}
//重写toString方法
@Override
public String toString() {
//返回重新定义的需要返回的值
return name + " " + age;
}
//JavaBean
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
-epuals()方法
- public boolean equals(Object obj) { }
- 默认实现为(this == obj),比较两个对象的地址是否相同
- 也可以进行重写,比较两个对象的内容是否相同或实现程序所需的需求
public class equalsTest {
public static void main(String[] args) {
//获取Man类的实例对象
Man m1 = new Man("iFinder",24);
Man m2 = new Man("Bobjoy",16);
Man m3 = new Man("iFinder",24);
//判断对象是否相等
//System.out.println(m1.equals(m2)); //输出:false
//System.out.println(m1.equals(m3)); //输出:false
//虽然m1与m3的属性值相同但是在内存中是开辟了不同的空间来存储他们的
//如果想实现,属性相同则返回true,则可以通过重写equals方法来实现
System.out.println(m1.equals(m3)); //输出:true
}
}
class Man {
String name;
int age;
//构造器
public Man(String name, int age) {
this.name = name;
this.age = age;
}
//重写equals方法
@Override
public boolean equals(Object obj) {
if (obj == null) return false; //防止传入的比较对象为空
if (this == obj) return true; //如果传入相同对象直接返回
if(obj instanceof Man) { //判断传入对象是否与比较对象有相同的父类,或同种类型
Man m = (Man)obj; //进行强制类型转换,确保二者的类型相同
if(this.name.equals(m.name) && this.age == m.age){ //比较需要程序实现比较的属性
return true;
}
}
return false;
}
}
-finalize()方法
- 当对象被判定为垃圾对象时,有JVM自动调用此方法,用于标记垃圾对象,进入回收队列。
- 垃圾对象:没有有效的引用指向此对象时,JVM判断为垃圾对象
- 垃圾回收:由GC销毁垃圾对象,释放数据存储空间
- 自动回收机制:JVM的内存耗尽,一次性回收所有的垃圾对象
- 手动回收机制:使用System.gc( );通知JVM执行垃圾回收
告诉GC需要回收垃圾,但是JVM是否回收由当前的运行情况所决定- finalize方法已经被弃用 -详见大神博文-
public class finalizeTest {
public static void main(String[] args) {
new Man1("iFinder",24);
new Man1("Bobjoy",16);
//显示调用垃圾回收方法
System.gc();
try { //模拟延时,保证对象已经被判定为垃圾对象
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("回收垃圾");
}
}
class Man1 {
String name;
int age;
//构造器
public Man1(String name, int age) {
this.name = name;
this.age = age;
}
//重写finalize方法
@Override
protected void finalize() throws Throwable {
System.out.println(this.name + "该对象已经被回收");
super.finalize();
}
}