栏目分类:
子分类:
返回
终身学习网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
终身学习网 > IT > 软件开发 > 后端开发 > Java

学习java第二十四天,匿名内部类、Object类、包装类的学习

Java 更新时间:发布时间: 百科书网 趣学号
一、匿名内部类
  • 匿名内部类是一个没有类名的局部内部类!(一切特征都是与局部内部类相同!)
  • 必须继承一个父类或者实现一个接口!
  • 定义类、实现类、创建对象的语法合并,只能创建一个该类的对象
  • 优点:减少代码量
  • 缺点:可读性较差

先编写一个USB接口,让其他类去实现这个接口

package com.ClassTest.Anonymous;
//接口
public interface USB {
    //服务方法
    void service();
}

在编写实现接口类

package com.ClassTest.Anonymous;
//测试
public class TestUSB {
    //重写服务
    public static void main(String[] args) {
        //使用匿名内部类优化(相当于创建了一个局部内部类)
            USB usb = new USB() {
                @Override
                public void service() {
                    System.out.println("链接电脑成功,风扇开始启动了。。。。。");
                }
            };
            usb.service();
    }

}

综上,可以看出,正常的一个接口是不能被实例化的,而以上代码直接将接口进行实例化,说白了就是默认创建了一个匿名内部类,是我们看不到的类,这个是跟局部内部类一样的,都是在方法中所创建,而这个匿名类内部类就是在main方法的下面!可以打开class文件目录查看一下是否生成新的文件!


可以看出,系统是默认生成了一个TestUSB$1的class文件,这个就是匿名内部类文件!

二、Object类

概述:Object类是一个超类、基类,所有类的直接或间接父类,位于继承树的最顶层!
任何类,如没有书写extends显示继承某个类,都默认直接继承Object类,否则为间接间接继承!
Object类中所定义的方法,是所有对象都具备的方法!
Object类型可以存储任何对象:作为参数,可以接受任何对象。作为返回值,可以返回任何对象!

方法摘要
  • clone():创建并返回此对象的一个副本。
  • equals(object obj):指示其他某个对象是否与此对象“相等”。
  • finalize():当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
  • getClass():返回此object的运行时类。
  • hashCode():返回该对象的哈希码值!
  • notify():唤醒在此对象监视器上等待的单个线程
  • notifyAll():唤醒在此对象监视器上等待的所有线程
  • toString():返回该对象的字符串表示。
  • wait():在其他线程调用此对象的notify()方法或notifyAll()方法前,导致当前线程等待。
  • wait(long timeout):在其他线程调用此对象的notify()方法或notifyAll()方法,或超过指定的时间量前,导致当前线程等待。
  • wait(long timeout,int namos):在其他线程调用此对象的notify()方法或notifyAll()方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量前,导致当前线程等待。
一、getClass方法
  • public final Class getClass(){}
  • 返回引用中存储的事迹对象类型
  • 应用:通常用于判断两个引用中实际存储对象类型是否一致

下面使用代码测试一下,首先创建一个普通类,用来封装属性

package com.ClassTest.Object.getClass;
//创建学生类,用来测试getClass运行时类是否相同
public class Student {
    private String name;
    private int age;
    //无参构造器
    public  Student(){


    }
        //有参构造器  参数列表是名字跟年龄
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    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;
    }
}


然后创造一个测试类,用来测试类是否一样!

package com.ClassTest.Object.getClass;

public class TestStudent {
    public static void main(String[] args) {

        Student s1 = new Student("菲",18);
        Student s2 = new Student("堂",18);
        Class class1 = s1.getClass();
        Class class2 = s2.getClass();
        if (class1.equals(class2)){
            System.out.println("s1跟s2属于同一个类型!");
        }else{
            System.out.println("s1跟s2不属于同一个类型!");
        }
    }
}

综上,可以看出s1跟s2的类是同一个类!

二、hashcode方法
  • public int hashCode(){}
  • 返回该对象的哈希码值
  • 哈希值根据对象的地址或字符串或数字使用hash算法计算出来的int类型的数值
  • 一般情况下相同对象返回相同哈希码值!

继续使用上面getClass方法中的测试类!

package com.ClassTest.Object.getClass;

public class TestStudent {
    public static void main(String[] args) {

        Student s1 = new Student("菲",18);
        Student s2 = new Student("堂",18);
        Class class1 = s1.getClass();
        Class class2 = s2.getClass();
        if (class1.equals(class2)){
            System.out.println("s1跟s2属于同一个类型!");
        }else{
            System.out.println("s1跟s2不属于同一个类型!");
        }
        Student s3 = s1;
        System.out.println(s1.hashCode());   //哈希值是1163157884
        System.out.println(s2.hashCode());   //哈希值是1956725890
        System.out.println(s3.hashCode());   //哈希值是1163157884
    }
}


综上,能看到如果输出s1对象中的哈希值,那就是1163157884,s2对象中的哈希值是1956725890,而s3等于s1的哈希值,所以跟s1的哈希值相同!

三、toString方法
  • public String toString(){}
  • 返回该对象的字符串表示(表现形式)
  • 可以根据程序需求覆盖该方法,如:展示对象各个属性值!

继续使用测试类,来查看toString方法返回的值

package com.ClassTest.Object.getClass;

public class TestStudent {
    public static void main(String[] args) {
        //1、getClass方法
        System.out.println("---------------1、getClass方法-------------------");
        Student s1 = new Student("菲",18);
        Student s2 = new Student("堂",18);
        Class class1 = s1.getClass();
        Class class2 = s2.getClass();
        if (class1.equals(class2)){
            System.out.println("s1跟s2属于同一个类型!");
        }else{
            System.out.println("s1跟s2不属于同一个类型!");
        }

        //2、hashCode方法
        System.out.println("---------------2、hashCode方法-------------------");
        Student s3 = s1;
        System.out.println(s1.hashCode());   //哈希值是1163157884
        System.out.println(s2.hashCode());   //哈希值是1956725890
        System.out.println(s3.hashCode());   //哈希值是1163157884
        
        //3、toString方法
        System.out.println("---------------3、toString方法-------------------");
        System.out.println(s1.toString());
        System.out.println(s2.toString());
        System.out.println(s3.toString());
    }
}


综上,我们得出的结果是类的全名称以及@符号的哈希值。这个@符号后的值跟上面hashCode方法得出的哈希值是一样的!显然这个结果不是我们自己想要的结果,不应是输出类的路径,应该是方法中的值,所以我们可以再重写一次这个toString的方法,也就是将返回值重写成name+age!

    public String toString(){   //在学生类中重写父类的toString方法
        return name+":"+age;
}

查看测试类的结果

综上,只要重写就能得出具体的值了!


四、equals()方法
  • public boolean equals(object obj){}
  • 默认实现为(this == obj),比较两个对象地址是否相同。
  • 可进行覆盖,比较两个对象的内容是否相同!

同样适用前面的测试方法,来测试是否相同

        //4、equals方法
        System.out.println("---------------4、equals方法-------------------");
        System.out.println(s1.equals(s2));
        Student s4 = new Student("小明",17);
        Student s5 = new Student("小明",17);
        System.out.println(s4.equals(s5));


综上,可以看出,这个结果都是返回的false,因为当前object类的equals方法,对比的是两个对象的地址!而不是值,如果想要值相同,那么就需要重写equals方法!

  • equals方法覆盖步骤:
  • 比较两个引用是否指向同一个对象
  • 判断obj是否为null
  • 判断两个引用指向的实际对象类型是否一致
  • 强制类型转换
  • 依次比较各个属性值是否相同

在以下Student类中去进行重写equals方法!

  public boolean equals(Object obj) {
        //1、判断两个引用是否指向同一个对象
      if (this == obj){
          return true;
      }
        //2、判断obj是否为null
     if (obj == null){
         return false;
     }
        //3、instanceof判断两个引用指向的实际对象类型是否相同
       if (obj instanceof Student) {
           //类型转换
            Student s = (Student) obj;
           //4、依次比较各个属性值是否相同
           if (this.name.equals(s.getName())&&this.age == s.getAge()){
               return true;
           }

       }
        return false;
    }

综上结果,可以看出,重写方法之后返回的内容跟我预想的就一样了!

五、finalize()方法
  • 当对象被判定为垃圾对象时,由JVM自动调用此方法,用以标记垃圾对象,进入回收队列
  • 垃圾对象:没有有效引用指向此对象时,为垃圾对象
  • 垃圾回收:由GC销毁垃圾对象,释放数据存储空间。
  • 自动回收机制:JVM的内存耗尽,一次性回收所有垃圾对象。
  • 手动回收机制:使用System.gc(); 通知JVM执行垃圾回收!

首先将finalize方法进行重写,因为需要准确的看到输出内容!一样是在Student类中重写!

        //重写funalize方法
    protected void finalize()throws Throwable{
        System.out.println(this.name+"对象被回收了!");

    }

然后新建一个Student2的类,用来测试输出!

package com.ClassTest.Object.getClass;

public class Student2 {
    public static void main(String[] args) {
        //实例化一个对象
        Student s1 = new Student("aaa",20);
        Student s2 = new Student("bbb",20);
        Student s3 = new Student("ccc",20);

        //new一个对象,但是没有引用值,也就是没有被调用
        new Student("aaa",20);
        new Student("bbb",20);
        new Student("ccc",20);
        new Student("ddd",20);



        //5、finalize回收垃圾
        System.out.println("---------------5、finalize回收垃圾-------------------");
        System.gc();
        System.out.println("回收垃圾");
    }
}


综上,可以看出来,当实例化一个对象时,而这个对象并没有引用值去调用它,当你需要回收的时候,JVM就会判断它们是一个垃圾,然后进行回收,也就达到了清理内存的好处!


三 、包装类

什么是包装类 ?

  • 基本类型所对应的引用数据类型!
  • Object可统一所有数据,包装类的默认值是null
基本数据类型包装类型
btyeByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
booleanBoolean
charCharacter
类型转换与装箱、拆箱
  • 引用类型存放在堆里面
  • 数据基本类型存放在栈里面
  • 装箱:把栈里面的数据加载到堆里面叫装箱,也就是把基本类型转换成引用类型叫装箱
  • 拆箱:把堆里面的对象拿到栈里面叫拆箱,把引用类型转换成基本类型叫拆箱!
    创建一个Demo01的类,用来演示装箱与拆箱的操作
package com.ClassTest.Packaging;

public class Demo01 {
    public static void main(String[] args) {
        //自动装箱:基本类型转换成引用类型,也就是装箱
        int age = 30;
        Integer integer1 = age;
        System.out.println("自动装箱");
        System.out.println(integer1);
        System.out.println("*----------------------------------*");
        //自动拆箱:引用类型转换成基本类型,也就是拆箱
        int age2 = integer1;
        System.out.println("自动拆箱");
        System.out.println(age2);
    }
}

结果图

综上,可以看出是jdk1.5以上,便可以完成自动装箱跟拆箱的操作了!也就是基本类型与引用类型之间的互相转换


注:文章仅做个人学习日记,不做学习建议,学习来源:千峰教育

转载请注明:文章转载自 www.051e.com
本文地址:http://www.051e.com/it/986405.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 ©2023-2025 051e.com

ICP备案号:京ICP备12030808号