12 Java常用类(一)(内部类+object类+包装类)

简介: 12 Java常用类(一)(内部类+object类+包装类)

12.1 内部类

12.1.1 内部类的概念

内部类的概念:

  • 在一个类中定义的类,称之为内部类(InnerClass),外面的类的称之为外部类(OutClass)

内部类的分类:

  • 1、成员内部类
  • 2、静态内部类
  • 3、局部内部类
  • 4、匿名内部类

内部类的特点:

  • 1、内部类可以访问到外部类的私有成员,且不破坏封装性
  • 2、内部类也会生成.class文件。名为:外部类名$内部类名.class

外部类的特点:

  • 一个java 文件中可以编写多个类,但是只能有一个类能使用public修饰,称之为主类。主类名必须与文件名一致
  • 建议:以后开发中,一个java文件就编写一个类
public class OutClass {//外部类
  //内部类
  public class InnerClass{
    
  }
}
12.1.2 成员内部类

成员内部类

  • 1、成员内部类中只能定义非静态属性和方法
  • 2、成员内部类中可以访问外部类的成员,私有的可以,静态的也可以

成员内部类如何创建对象

  • 语法: 内部类 对象名 = new 外部类().new 内部类();
public class OuterClass1 {
  String name;
  private String hobby;
  static int age;
  public void show() {
    System.out.println("show()");
  }
  public class InnerClass{
    //定义属性
    int a ;
    //static int b; //错误  ,成员内部类中不能定义静态变量
    //定义方法
    public void m1() {
      System.out.println("成员内部类的成员变量"+a);
      System.out.println("外部类的成员变量"+name);
      System.out.println("外部类的私有成员变量"+hobby);
      System.out.println("外部类的静态变量"+age);
    }
//    public static void m2() {//错误  成员内部类中不能定义静态方法
//    }
  }
}
12.1.3 静态内部类

静态内部类

  • 1、静态内部类中可以定义属性和方法,也能定义静态属性和方法
  • 2、静态内部类中只能访问静态外部类的静态属性和方法

静态内部类创建对象

  • 语法:内部类 对象名 = new 外部类.内部类();
public class OuterClass2 {
  String name;
  static int age;
  private static String hobby;
  public static class InnerClass2{
    //定义属性
    int a;
    static int b;
    //定义方法
    public void m1() {
      //System.out.println("外部类的成员变量"+name);
      System.out.println("外部类的静态变量"+age);
      System.out.println("外部类的私有静态变量"+hobby);
    }
    public static void m2() {
    }
  }
}
12.1.4 局部内部类

局部内部类: 定义在方法中

特点:

  • 1、成员内部类中只能定义非静态属性和方法
  • 2、成员内部类中可以访问外部类的成员,私有的可以,静态的也可以
  • 3、局部内部类只能在方法内创建对象

面试题:


局部内部类只能访问局部常量。

在jdk1.7版本中,如果局部变量在局部内部类中使用必须要显式的加上final

在jdk1.8版本中,final是默认加上的

因为局部变量在方法结束后,就会被销毁,而局部内部类的对象却要等到内存回收机制进行销毁所以如果是常量的话,那么常量就会被存放在常量池中,

public class OuterClass4 {
  String name;
  private int age;
  static String hobby;
  public void show() {
    int num = 10;
    class InnerClass4{
      public void m1() {
        System.out.println("外部类的成员变量"+name);
        System.out.println("外部类私有的成员变量"+age);
        System.out.println("外部类静态变量"+hobby);
        //num = 20;
        System.out.println("访问局部变量"+num);
      }
      //static int b;
      //public static void m2() {}
    }
    InnerClass4 in = new InnerClass4();
    in.m1();
  } 
}
2.1.5 匿名内部类

匿名内部类:本身就是一个对象

语法:

new 父类(){

重写父类的方法

}

特点:

  • 1、匿名内部类本身就是一个对象
  • 2、一般在匿名内部类中不会定义属性和方法,因为没有意义
  • 3、匿名内部类的父类一般都是抽象类或者是接口

匿名内部类的应用场景

  • 如果一个方法的参数是接口,且这个接口只需要实现一次,那么就可以使用匿名内部类
  • 这个接口的实现每一次都不相同,就可以使用匿名内部类
Father f = new Father() {
    int a;
    public void m1() {
        System.out.println("m1()...");
    }
};

匿名内部类的应用场景

public class Test {
  public static void main(String[] args) {
        //使用匿名内部类作为参数传递
    gdbh(14,new MyInterface() {
      @Override
      public boolean isZS(int num) {
        for (int i = 2; i < num; i++) {
          if(num % i == 0) {
            return false;
          }
        }
        return true;
      }
    });
  }
  public static void gdbh(int num,MyInterface mi) {
    for (int i = 3; i <= num/2; i++) {
      if(mi.isZS(i) && mi.isZS(num-i)) {
        System.out.println(num+"="+i+"+"+(num-i));
      }
    }
  }
}
interface MyInterface{
  boolean isZS(int num);
}
12.1.6 内部类中this用法

this表示当前类对象

  • 如果有内部类,那么this在哪个类中使用就是指的哪个类的当前类的对象
  • 如果要想调用外部类的属性和方法,那么需要使用外部类名.this.属性或者方法名
public class OuterClass3 {
  String name = "张三"; 
  public class InnerClas3{
    String name ="李四";    
    public void m1() {
      String name = "王五";
      System.out.println("方法中的name"+name);
      System.out.println("内部类中的name"+this.name);
      //this关键字表示的时候当前类的对象,如果在内部类中this表示的是内部类的对象,
            //如果想要表示外部类的对象,外部类名.this
      System.out.println("外部类中的name"+OuterClass8.this.name);
    }
  }
}

12.2 Object类

12.2.1 概念

Object 类

  • 1、Object 是所有的类的超类、基类。位于继承树的最顶层。
  • 2、任何一个没有显示定义extends父类的类。都直接继承Object,否则就是间接继承
  • 3、任何一个类都可以享有Object提供的方法

4、Object类可以代表任何一个类(多态),可以作为方法的参数、方法的返回值

12.2.2 Object中常用方法
12.2.2.1 getClass方法

此方法用于返回该对象的真实类型(运行时的类型)

  • public final Class<?> getClass()
//判断运行时d对象和c对象是否是同一个类型
Animal d = new Dog();
Animal c = new Cat();

//方式1:通过 instanceof 关键字判断
if((d instanceof Dog && c instanceof Dog) ||(d instanceof Cat && c instanceof Cat)) {
    System.out.println("是同一个类型");
}else {
    System.out.println("不是同一个类型");
}
//方式2:通过getClass方法 判断
if(d.getClass() == c.getClass()) {
    System.out.println("是同一个类型");
}else {
    System.out.println("不是同一个类型");
}
12.2.2.2 hashCode方法

public native int hashCode();

  • 1、返回该对象的十进制的哈希吗值
  • 2、hash值是由hash算法通过对象的地址、对象中的字符串、数字等,计算出来的
  • 3、相同的对象应当返回相同的哈希吗值,不同的对象尽量返回不同的哈希码值
Student stu1 = new Student("zhangsan", 30);
Student stu2 = new Student("zhangsan", 30);
Student stu3 = stu1;
System.out.println(stu1.hashCode());
System.out.println(stu2.hashCode());
System.out.println(stu3.hashCode());

//hash突出
String str1 = "通话";
String str2 = "重地";

System.out.println(str1.hashCode());
System.out.println(str2.hashCode());
12.2.2.3 toString方法

返回对象的字符串表现形式

  • 全限定名+@+十六进制的hash值(地址)
  • 如果直接输出一个对象,那么默认会调用这个对象的toString方法,而toString方法是Object类提供的,返回的是“对象的地址”。但是我们一般输出对象希望输出的是对象的属性信息,所以可以重写父类的toString方法
@Override
public String toString() {
    return "Student [name=" + name + ", age=" + age + "]";
}
12.2.2.4 equals方法

Object类的equals方法的作用是比较两个对象是否相等。比较的是内存地址。其底层代码的是==

如果不想比较内存地址,那么需要重写equals方法

Student stu1 = new Student("zhangsan", 30);
Student stu2 = new Student("zhangsan", 30);

//重写equals方法之前
System.out.println(stu1 == stu2); //false
System.out.println(stu1.equals(stu2));//false

//希望如果两个对象的属性一样,就认为两个对象是相同的对象
//重写equals方法之后
System.out.println(stu1 == stu2); //false
System.out.println(stu1.equals(stu2));//true

System.out.println(stu1.hashCode());
System.out.println(stu2.hashCode());

重写equals方法

public boolean equals(Object obj) { 
    //1、非空判断
    if(obj == null) {
        return false;
    }
    //2、如果当前对象与obj相等
    if(this == obj) {
        return true;
    }
    //3、判断obj是否属于Student类型
    if(obj instanceof Student) {
        Student stu = (Student)obj;
        //4、判断属性
        if(this.name.equals(stu.name) && this.age == stu.age) {
            return true;
        }
    }
    return false;
}

总结:== 和 equals的区别

  • 两个东西都是用于比较的
  • == 可以用于基本类型和引用类型
  • ==在基本类型的比较中,比较的值是否相等,如果相等返回true,否则返回false
  • ==在引用类型的比较中,比较的地址是否相等,如果相等返回true,否则返回false

equals只能用于引用类型的比较

  • equals方法是Object类提供的方法,其底层实现是==比较,所以在没有重写父类的equals方法时。比较的也是地址。如果希望两个对象的属性一样,就认为两个对象是相同的对象,那么需要重写equals方法,但是重写了equals的同时也需要重写hashcode方法,因为java中约定两个对象相等,那么两个对象的hash值也应该相等
12.2.2.5 finalize方法

当垃圾回收器回收垃圾对象的时候,自动调用

public class Test5 {
  public static void main(String[] args) {
    Person p = new Person();
    //手动将对象标记为垃圾对象
    p = null;
    //触发垃圾回收器,回收垃圾对象
    System.gc();
  }
}
class Person{
  @Override
  protected void finalize() throws Throwable {
    super.finalize();//不要删除
    System.out.println("finalize方法执行了");
  }
}

12.3 包装类

12.3.1 概念

为什么要有包装类

  • 因为基本数据类型不具有方法和属性。而引用数据类型可以拥有属性和方法,使用更加的灵活
  • 所以Java给8种基本数据类型提供对应8个包装类。包装类也就是引用数据类型
基本类型 包装类型
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean
12.3.2 装箱和拆箱

装箱就是将基本类型转换成包装类

拆箱就是将包装类型转换成基本类型

jdk1.5 之前装箱和拆箱

//在jdk1.5之前   拆装箱的过程
byte b = 10;
//装箱
Byte b1 = Byte.valueOf(b);
System.out.println(b1);
//拆箱
byte b2 = b1.byteValue();
System.out.println(b2);

jdk1.5 之后的装箱和拆箱

//在jdk1.5之后   拆装箱的过程    
int i = 10;
//装箱
Integer i1 = i;
System.out.println(i1);
//装箱
int i2 = i1;
System.out.println(i2);
12.3.3 Number类

Byte、Short、Integer、Long、Float、Double六个子类

提供一组方法,用于将其中某一种类型转换成其他类型 xxxValue()方法

Integer a = 100;
Byte b = a.byteValue();
Short c = a.shortValue();
Long d = a.longValue();
Float e = a.floatValue();
Double f = a.doubleValue();
Integer g = a.intValue();
12.3.4 常用的包装类

Integer 、Double

12.3.4.1定义方式
//Integer、Double的定义方式
Integer ii1 = new Integer(100);
//或者
Integer ii1 = 100;
Double dd1 = new Double(100.2);
//或者
Double dd1 = 100.2;
12.3.4.2 常用的属性
System.out.println(Integer.MAX_VALUE);
System.out.println(Integer.MIN_VALUE);
System.out.println(Double.MAX_VALUE);
System.out.println(Double.MIN_VALUE);
12.3.4.3 常用的方法

将字符串类型的数值转换成int或者是double类型

//常用方法:
//将字符串转换成int或者是double
String s = "123";
//方式1:
int i = Integer.parseInt(s);
System.out.println(i);
//方式2:
int i2 = Integer.valueOf(s);
System.out.println(i2);

String s1 = "20.5";
//方式1:
double d = Double.parseDouble(s1);
System.out.println(d);
//方式2:
double d1 = Double.valueOf(s1);
System.out.println(d1);

//java.lang.NumberFormatException   数字格式化异常
String s2 = null;
System.out.println(Integer.parseInt(s2));
12.3.5 缓冲区(面试题)
public class Demo02 {
  public static void main(String[] args) {
        /**
     * 面试题:整数型包装类缓冲区
     * 整数型的包装类定义缓冲区(-128~127),如果定义的数在这个范围你之内,那么直接从缓存数组中获取,
     * 否则,重新new新的对象
     */
    Integer i1 = new Integer(10);
    Integer i2 = new Integer(10);
    System.out.println(i1 == i2); //false
    System.out.println(i1.equals(i2));//true
    
    Integer i3 = 1000; //Integer i3 = new  Integer(1000);
    Integer i4 = 1000; //Integer i3 = new  Integer(1000);
    System.out.println(i3 == i4); //false
    System.out.println(i3.equals(i4));//true
    
    Integer i5 = 100; //IntegerCache.cache[i + (-IntegerCache.low)]
    Integer i6 = 100; //IntegerCache.cache[i + (-IntegerCache.low)]
    System.out.println(i5 == i6);//true
    System.out.println(i5.equals(i6));//true  
  }
}


目录
相关文章
|
9天前
|
存储 缓存 安全
java 中操作字符串都有哪些类,它们之间有什么区别
Java中操作字符串的类主要有String、StringBuilder和StringBuffer。String是不可变的,每次操作都会生成新对象;StringBuilder和StringBuffer都是可变的,但StringBuilder是非线程安全的,而StringBuffer是线程安全的,因此性能略低。
|
18天前
|
安全 Java
Java多线程集合类
本文介绍了Java中线程安全的问题及解决方案。通过示例代码展示了使用`CopyOnWriteArrayList`、`CopyOnWriteArraySet`和`ConcurrentHashMap`来解决多线程环境下集合操作的线程安全问题。这些类通过不同的机制确保了线程安全,提高了并发性能。
|
21天前
|
存储 缓存 Java
大厂面试必看!Java基本数据类型和包装类的那些坑
本文介绍了Java中的基本数据类型和包装类,包括整数类型、浮点数类型、字符类型和布尔类型。详细讲解了每种类型的特性和应用场景,并探讨了包装类的引入原因、装箱与拆箱机制以及缓存机制。最后总结了面试中常见的相关考点,帮助读者更好地理解和应对面试中的问题。
43 4
|
22天前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
76 4
|
23天前
|
Java 编译器 开发者
Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面
本文探讨了Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面,帮助开发者提高代码质量和程序的健壮性。
44 2
|
2月前
|
Java
Java Object 类详解
在 Java 中,`Object` 类是所有类的根类,每个 Java 类都直接或间接继承自 `Object`。作为所有类的超类,`Object` 定义了若干基本方法,如 `equals`、`hashCode`、`toString` 等,这些方法在所有对象中均可使用。通过重写这些方法,可以实现基于内容的比较、生成有意义的字符串表示以及确保哈希码的一致性。此外,`Object` 还提供了 `clone`、`getClass`、`notify`、`notifyAll` 和 `wait` 等方法,支持对象克隆、反射机制及线程同步。理解和重写这些方法有助于提升 Java 代码的可读性和可维护性。
|
7月前
|
Java
Java Object 类
5月更文挑战第16天
|
4月前
|
Java
【Java基础面试二十】、介绍一下Object类中的方法
这篇文章介绍了Java中Object类的常用方法,包括`getClass()`、`equals()`、`hashCode()`、`toString()`、`wait()`、`notify()`、`notifyAll()`和`clone()`,并提到了不推荐使用的`finalize()`方法。
【Java基础面试二十】、介绍一下Object类中的方法
|
3月前
|
Python
类与面向对象编程(Object-Oriented Programming, OOP)
类与面向对象编程(Object-Oriented Programming, OOP)
|
4月前
|
前端开发 Java 编译器
【前端学java】java中的Object类和前端中的Object有什么区别(9)
【8月更文挑战第10天】java中的Object类和前端中的Object有什么区别
45 0
【前端学java】java中的Object类和前端中的Object有什么区别(9)