Java中的String实例化、Annotation注解类、继承的多态和Object类(附带相关面试题)

简介: 1.java中String两种实例化对象2.Annotation注解类 3.继承的多态 4.Object类

1.java中String两种实例化对象

在Java中String并不是一个数据类型,而是引用数据类型

创建方式的区别

作为特殊类,其创建方式有两种

String strA= "mldn";
String str = "mldn";
String strB = new String("mldn");

image.gif

下面介绍其区别:

image.gif编辑

strA在堆上创建mldn空间,而strB的实例化中有new 即新创建一个空间内容也是mldn,而strc内容是mldn与strA是一致的,所以不会再分配新的空间,而是直接将strC的栈地址直接指向strA的堆地址

*面试题new String("a") + new String("b") 会创建几个对象?

对象1:new StringBuilder()

对象2:new String("a")

对象3:常量池中的"a"

对象4:new String("b")

对象5:常量池中的"b"

深入剖析:StringBuilder中的toString():

对象6:new String("ab")

强调一下,toString()的调用,在字符串常量池中,没有生成"ab"

面试题 String str="i"与 String str=new String(“i”)一样吗?

String str="i"会将起分配到常量池中,常量池中没有重复的元素,如果常量池中存中i,就将i的地址赋给变量,如果没有就创建一个再赋给变量。

String str=new String(“i”)会将对象分配到堆中,即使内存一样,还是会重新创建一个新的对象。


2.Annotation注解类

1.@Override 准确性覆写类

覆写发生在子类中有一个和父类相同方法名、相同参数列表和相同返回类型的方法时。在一般情况下,通过子类对象调用该方法时,会直接调用子类中的方法。这是因为子类方法覆盖了父类方法,所以会优先调用子类的方法实现。

然而,如果在某些情况下出现错误,可能会导致错误地调用父类的方法,例如:

    1. 子类方法的签名与父类方法不一致:如果子类中定义的方法签名与父类的方法签名不完全匹配,例如参数列表不同,那么不会发生准确性覆写,而是子类创建了一个新的方法,和父类的方法没有关联。此时,通过子类对象调用方法时,会调用到父类的方法。
    2. 在子类中使用了super关键字:子类中可以使用super关键字调用父类的方法,即使发生了准确性覆写。在这种情况下,通过super关键字调用的是父类的方法,而不是子类的方法。

    所以通过@Override就可以避免出现上述问题从而正常调用子类

    package Example82;
    class father{
        public void function(){
            System.out.println("执行父亲函数的");
        }
    }
    class son extends father{
        @Override
        public void function(){
            System.out.println("利用@Override准确性覆写执行子函数");
        }
    }
    public class javaDemo {
        public static void main(String[] args) {
        son s = new son();
        s.function();
        }
    }

    image.gif

    image.gif编辑

    2.@Deprecated过期声明注解

    当一个类可能已经不符合生产的需求后,但是如果随便删除这个类可能会导致整个程序结构的不稳定从而出错,所以java中就有@Deprecated过期声明注解,在用该注解后某个类或者某个方法将不再建议使用。如果调用则会在方法上加上删除线

    image.gif编辑

    *面试题: 在 Java 中,什么时候用重载,什么时候用重写?

    (1)重载是多态的集中体现,在类中,要以统一的方式处理不同类型数据的时候,可以用重载。

    (2)重写的使用是建立在继承关系上的,子类在继承父类的基础上,增加新的功能,可以用重写。

    (3)简单总结:

    重载是多样性,重写是增强剂;

    目的是提高程序的多样性和健壮性,以适配不同场景使用时,使用重载进行扩展;

    目的是在不修改原方法及源代码的基础上对方法进行扩展或增强时,使用重写;

     


    3.多态

    1.向上转型

    向上转型 即大范围转到小范围 比如 动物和狗,动物就是父类,狗是子类,这种往下细分的操作就叫向上转型

    父类 name = new 子类();

    为什么要出现向上转型

      1. 统一接口:通过向上转型,可以将不同子类的对象都当作父类类型来处理。这样可以使用统一的接口对这些对象进行操作,简化了代码的编写和维护。如果有多个子类,使用向上转型可以避免针对每个子类都编写相似的代码段,提高了代码的重用性。
      2. 扩展性:通过向上转型,可以更加方便地扩展代码,增加新的子类,而无需修改已有的代码。这是因为向上转型使得代码与具体子类解耦,如果需要增加一个新的子类,只需要修改创建对象的部分,而不需要修改其他已经存在的代码逻辑。
      3. 可替换性:通过向上转型,可以实现对子类对象的替换。即使使用父类引用变量来引用子类对象,仍然可以调用子类中重写的方法,实现对父类引用的灵活使用。这使得程序在后续的维护和扩展过程中更加方便,可以根据需要轻松地切换不同的子类实现。
      package Example84;
      class Animal {
          public void sound() {
              System.out.println("Animal makes sound");
          }
      }
      class Dog extends Animal {
          @Override
          public void sound() {
              System.out.println("Dog barks");
          }
          public void playFetch() {
              System.out.println("Dog plays fetch");
          }
      }
      class Cat extends Animal {
          @Override
          public void sound() {
              System.out.println("Cat barks");
          }
          public void playFetch() {
              System.out.println("Cat plays fetch");
          }
      }
      public class javaDemo {
          public static void main(String[] args) {
              Animal animal = new Dog(); // 向上转型
              animal.sound();
              animal = new Cat();
              animal.sound();
          }
      }

      image.gif

      image.gif编辑

      通过向上转型,我们可以实例化一个 Animal 对象,并且通过该对象引用子类对象,从而灵活地切换它们之间的关系。然而,向上转型有一个重要限制,即我们只能调用父类中定义的方法,或者子类中覆盖了的方法。这意味着,一些子类特有的功能将无法直接通过父类引用调用。例如,在上述代码中,我们可以使用 animal.sound() 调用 Animal 类中的 sound 方法,但无法使用 animal.playFetch() 调用 Dog 或 Cat 类特有的 playFetch 方法。

      为此就有了向下转型

      2.向下转型

      条件:必须要在向上转型的基础上才能进行向下转型,否则父类与子类无关联的情况下无法进行联系

      案例代码:

      package Example84;
      class Animal {
          public void sound() {
              System.out.println("Animal makes sound");
          }
      }
      class Dog extends Animal {
          @Override
          public void sound() {
              System.out.println("Dog barks");
          }
          public void playFetch() {
              System.out.println("Dog plays fetch");
          }
      }
      public class javaDemo {
          public static void main(String[] args) {
              Animal animal = new Dog(); // 向上转型
              ((Dog) animal).playFetch();//强制向下转型
              Dog dog = (Dog) animal;//第二种强制向下转型
              dog.playFetch();
          }
      }

      image.gif

      image.gif编辑

      3.instanceof关键字(判断是否能向下转型)

      当使用了向上转型后,将子类的实例赋值给父类的引用变量时,就会丧失对子类特有方法的直接访问能力。此时,如果想要调用子类的方法,就需要进行安全转型,即使用 instanceof 检查对象是否为某个特定类型,并在确认类型后进行强制转型。

      在这种情况下,如果我们直接调用子类的方法而没有进行安全转型,会导致编译错误,因为编译器只知道引用变量的静态类型,而无法确定运行时实际对象的类型。这样的错误可能会导致程序在运行时抛出 ClassCastException 异常,因为尝试将父类引用转换为子类类型是非法的。

      用法:  实例化对象名称 instanceof 类  返回boolean类型的值

      package Example84;
      class Animal {
          public void sound() {
              System.out.println("Animal makes sound");
          }
      }
      class Dog extends Animal {
          @Override
          public void sound() {
              System.out.println("Dog barks");
          }
      }
      public class javaDemo {
          public static void main(String[] args) {
             Animal animal = new Animal();
              System.out.println(animal instanceof Animal);
              System.out.println(animal instanceof Dog);
             Animal animal1 = new Dog();
              System.out.println(animal1 instanceof Animal);
              System.out.println(animal1 instanceof Dog);
          }
      }

      image.gif

      image.gif编辑

      具体应用

      image.gif编辑


      4.Object类

      1.概述

      1.在Java中,Object类是所有类的根类,也可以说是所有类的父类。它定义了一些通用的方法,如equals()hashCode()toString()等。当我们定义一个类时,如果没有显式指定它的父类,那么默认情况下该类会直接继承自Object类。因此,你可以将其视为所有类的隐式父类。

      然而,并不是所有类型的数据都可以被向上转型为Object类型。在Java中,基本类型(如intbooleanchar等)是不能直接向上转型为Object类型的。相反,只有引用类型(如类、接口等)可以被向上转型为Object类型。

      在Java中,当我们将一个引用类型的对象向上转型为Object类型时,它实际上已经是Object类型的对象了,但是我们只能通过Object类型的引用变量访问 Object 类中定义的方法,无法直接调用原始类型的方法。如果我们想要调用原始类型的方法,就需要进行向下转型(即安全强制类型转换)。

      因此,尽管Object类可以作为所有类的父类,但并不意味着它可以接受所有类型的数据。只有引用类型可以被向上转型为Object类型,而基本类型不能。同时,为了调用子类特有的方法,还需要进行向下转型。

      2.Object的toString方法

      package Example84;
      class Animal extends Object{
          public void sound() {
              System.out.println("Animal makes sound");
          }
      }
      class Dog extends Animal {
          @Override
          public void sound() {
              System.out.println("Dog barks");
          }
          public void fectch(){
              System.out.println("Dog fectch");
          }
          @Override
          public String toString(){
              return "直接打印一个类,其实是调用了Object类中的toString函数";
          }
      }
      public class javaDemo {
          public static void main(String[] args) {
             Animal animal = new Dog();
              System.out.println(animal);
          }
      }

      image.gif

      image.gif编辑

      面试题:hashcode是什么?有什么作用?

      Java中Object有一个方法:

      public native int hashcode();

      (1)hashcode()方法的作用

      1.hashcode()方法主要配合基于散列的集合(相关知识在java的类集中进行学习)一起使用,比如HashSet、HashMap、HashTable。

      当集合需要添加新的对象时,先调用这个对象的hashcode()方法,得到对应的hashcode值,实际上hashmap中会有一个table保存已经存进去的对象的hashcode值,如果table中没有改hashcode值,则直接存入,如果有,就调用equals方法与新元素进行比较,相同就不存了,不同就存入。

      (2)equals和hashcode的关系

      如果equals为true,hashcode一定相等;

      如果equals为false,hashcode不一定不相等;

      如果hashcode值相等,equals不一定相等;

      如果hashcode值不等,equals一定不等;

      (3)重写equals方法时,一定要重写hashcode方法

      Object还有非常多的方法将在以后章节展现

      目录
      相关文章
      |
      6月前
      |
      安全 IDE Java
      重学Java基础篇—Java Object类常用方法深度解析
      Java中,Object类作为所有类的超类,提供了多个核心方法以支持对象的基本行为。其中,`toString()`用于对象的字符串表示,重写时应包含关键信息;`equals()`与`hashCode()`需成对重写,确保对象等价判断的一致性;`getClass()`用于运行时类型识别;`clone()`实现对象复制,需区分浅拷贝与深拷贝;`wait()/notify()`支持线程协作。此外,`finalize()`已过时,建议使用更安全的资源管理方式。合理运用这些方法,并遵循最佳实践,可提升代码质量与健壮性。
      184 1
      【Java集合类面试二十八】、说一说TreeSet和HashSet的区别
      HashSet基于哈希表实现,无序且可以有一个null元素;TreeSet基于红黑树实现,支持排序,不允许null元素。
      |
      9月前
      |
      JSON Java Apache
      Java基础-常用API-Object类
      继承是面向对象编程的重要特性,允许从已有类派生新类。Java采用单继承机制,默认所有类继承自Object类。Object类提供了多个常用方法,如`clone()`用于复制对象,`equals()`判断对象是否相等,`hashCode()`计算哈希码,`toString()`返回对象的字符串表示,`wait()`、`notify()`和`notifyAll()`用于线程同步,`finalize()`在对象被垃圾回收时调用。掌握这些方法有助于更好地理解和使用Java中的对象行为。
      117 8
      |
      安全 Java 应用服务中间件
      JVM常见面试题(三):类加载器,双亲委派模型,类装载的执行过程
      什么是类加载器,类加载器有哪些;什么是双亲委派模型,JVM为什么采用双亲委派机制,打破双亲委派机制;类装载的执行过程
      282 35
      JVM常见面试题(三):类加载器,双亲委派模型,类装载的执行过程
      |
      10月前
      |
      存储 Java 程序员
      Java基础的灵魂——Object类方法详解(社招面试不踩坑)
      本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
      391 4
      |
      11月前
      |
      Java
      Java Object 类详解
      在 Java 中,`Object` 类是所有类的根类,每个 Java 类都直接或间接继承自 `Object`。作为所有类的超类,`Object` 定义了若干基本方法,如 `equals`、`hashCode`、`toString` 等,这些方法在所有对象中均可使用。通过重写这些方法,可以实现基于内容的比较、生成有意义的字符串表示以及确保哈希码的一致性。此外,`Object` 还提供了 `clone`、`getClass`、`notify`、`notifyAll` 和 `wait` 等方法,支持对象克隆、反射机制及线程同步。理解和重写这些方法有助于提升 Java 代码的可读性和可维护性。
      363 20
      |
      11月前
      |
      JSON 调度 数据库
      Android面试之5个Kotlin深度面试题:协程、密封类和高阶函数
      本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点。文章详细解析了Kotlin中的协程、扩展函数、高阶函数、密封类及`inline`和`reified`关键字在Android开发中的应用,帮助读者更好地理解和使用这些特性。
      236 1
      |
      11月前
      |
      Java
      java构造方法时对象初始化,实例化,参数赋值
      java构造方法时对象初始化,实例化,参数赋值
      275 1
      |
      存储 Java
      【Java集合类面试二十九】、说一说HashSet的底层结构
      HashSet的底层结构是基于HashMap实现的,使用一个初始容量为16和负载因子为0.75的HashMap,其中HashSet元素作为HashMap的key,而value是一个静态的PRESENT对象。
      【Java集合类面试三十】、BlockingQueue中有哪些方法,为什么这样设计?
      BlockingQueue设计了四组不同行为方式的方法用于插入、移除和检查元素,以适应不同的业务场景,包括抛异常、返回特定值、阻塞等待和超时等待,以实现高效的线程间通信。

      热门文章

      最新文章