JavaRush /Java 博客 /Random-ZH /Java 开发人员访谈问答分析。第五部分

Java 开发人员访谈问答分析。第五部分

已在 Random-ZH 群组中发布
你好你好!如今,Java 开发人员的需求量很大。当然,我不能为你提供一个空缺,但我会尽力帮助你获得新知识并弥补一些差距。因此,我们继续分析250 多个Java 开发人员面试问题。分析前面部分的链接位于文章末尾。Java 开发人员访谈问答分析。 第 5 - 1 部分

39. Java中的访问修饰符是什么?说出他们的名字。它们有什么用?

我之前在有关 Java 封装元素的问题中描述了访问修饰符。但无论如何我都会提醒你。Java 中的访问修饰符是描述授予特定 Java 组件的访问级别的关键字。访问修饰符可以是:
  • public - 具有此修饰符的元素将可公开访问。那些。使用 public 修饰符声明的字段和方法、类对于当前包和外部包中的其他类都是可见的;
  • protected - 具有此修饰符的元素可以从当前包的当前类或后代类中的任何位置访问,即使它们位于其他包中;
  • default或缺少修饰符 - 当根本未指定访问修饰符时,隐式使用此修饰符。它与前一个类似,不同之处在于其他包中的后代类允许可见性;
  • private是所有修饰符中最私有的,仅允许访问当前类中的元素。
Java 开发人员访谈问答分析。 第 5 - 2 部分

40.说出静态方法和变量方法的主要特征

一个非常奇怪的提法——“可变方法”。当然,这是指普通的非静态方法。因此,主要区别在于静态方法属于类,实际上,对于它们,您不需要创建此类的实例:只能使用类类型来调用它。例如,我们有一个静态方法来抚摸猫:
public class CatService {
   public static void petTheCat(Cat cat) {
       System.out.println("Погладить кота - " + cat.getName());
   }
我们不需要CatService 类的实例来调用它:
Cat cat = new Cat(7, "Bobi");
CatService.petTheCat(cat);
虽然普通方法绑定(属于)一个对象,并且为了调用它们,您必须有一个将在其上调用该方法的实例(对象)。例如,猫有一个非静态方法 - meowing:
class Cat {
   public void mew() {
       System.out.println("Meow! Meow! Meow!");
   }
要调用此方法,我们需要猫的特定实例:
Cat cat = new Cat(7, "Bobi");
cat.mew();

41. 静态和“变量”方法的主要限制是什么?

正如我之前所说,常规方法的主要限制是必须始终存在某个实例来调用该方法。但是静态方法不需要 this,但它不能引用this引用(指向当前对象的元素),因为当前对象不存在。

42. static关键字是什么意思?静态方法可以被重写或重载吗?

static关键字指定的元素不属于类的对象,而是属于类,并且在加载类本身时加载。静态元素是整个程序的唯一元素,而常规元素是特定对象的唯一元素。静态可以是:
  • 类字段;
  • 类初始化块;
  • 类方法;
  • 类的内部类(但是,这仍然是同义反复)。
静态方法不能被覆盖:它属于类并且不被继承,但同时它可以被重载。

43. 一个方法可以同时是静态的和抽象的吗?

我在上一篇文章中已经提到过:方法不能同时是抽象的和静态的。方法的抽象性意味着它必须在后继者中被重写。同时,静态方法属于类并且不能被重写:这会导致矛盾,编译器会看到并开始咒骂。如果你有这样的情况,你应该认真思考你的应用程序架构的正确性(毕竟,它显然有问题)。Java 开发人员访谈问答分析。 第 5 - 3 部分

44. 是否可以在常规方法中使用静态方法?反之亦然?为什么?

静态方法可以在常规方法中使用,因为没有什么可以阻止这一点。同时,相反的情况是不可能的:静态方法不能在没有对该类的特定实例的引用的情况下使用常规方法。正如我们所记得的,this引用不适用于静态类成员:可以有任意多个类的特定对象,并且每个对象内部都会有一个对其自身的引用 - this。那么您如何理解您需要选择哪个特定的链接呢?但没办法。因此,静态元素不能引用非静态元素,除非引用特定对象。实际上,静态方法只有在引用特定对象时才可以使用非静态方法。例如,作为参数出现的一个:
public static void petTheCat(Cat cat) {
   System.out.println("Погладить кота - " + cat.getName());
}
这里我们看到静态方法petTheCat调用Cat对象的普通非静态方法- getName

45.什么是接口?能有最终的界面吗?

我们记得,Java 中没有多重继承。接口是它的一种替代方案。该界面看起来像是一个非常精简的类。它们定义功能时没有具体的实现,而是由实现(实现)这些接口的类来实现。界面示例:
public interface Animal {
    void voice();
}
类实现接口的示例:
class Cat implements Animal {

   @Override
   public void voice() {
       System.out.println("Meow! Meow! Meow!");
   }
}
关于使用接口,您需要了解的主要内容是:
  1. 接口方法应该只包含一个标头,没有特定的方法体,即 必须是抽象的(但不使用abstract关键字)。静态方法和默认方法除外,它们需要方法体。
  2. 一个类可以实现许多接口(正如我所说,这是多重继承的替代方案),这些接口用逗号分隔:class Lion Implements Animal, Wild
  3. 接口是使用关键字-interface创建的。
  4. 当通过类实现接口时,使用关键字 - Implements
  5. 实现特定接口的类必须实现其所有抽象方法,或者必须将自身声明为抽象。
  6. 使用接口的主要目的是实现多态性(对象采取多种形式的能力)。
  7. 一般来说,方法的访问修饰符不会写在接口中:它们默认是public 的,并且不能指定除public之外的其他修饰符。从 Java 9 开始,您可以对方法使用private修饰符。
  8. 接口变量默认是 static final,换句话说,是常量:它们总是需要直接在接口中初始化。
  9. 您无法创建接口对象。
接口是否可以是final的这个问题的答案当然是不能。毕竟,接口的本质就是要实现。我们都记得很清楚,类级别的Final使其不可继承,而对于接口而言,则使其不可实现。为什么我们需要一个无法实现和使用的接口?没错——没必要!编译器是这么认为的))Java 开发人员访谈问答分析。 第 5 - 4 部分这个含义只是在Java 8的接口中引入静态方法时才出现的,但这并没有改变接口不能是final的事实。我非常肤浅地谈论了接口,因为...... 这是一个广泛的话题。请阅读有关Java 中的接口以及抽象类和接口之间的区别的文章,了解更多相关内容。

46. ​​哪里可以初始化静态字段?

静态字段可以初始化:
  • 直接在声明时通过等号=
  • 在静态初始化块中;
  • 在非静态初始化块中,但是你必须明白,每次创建对象时,该字段都会被这个初始化块覆盖;
  • 在类构造函数中。每次调用该构造函数时(即通过该构造函数创建对象时),该字段都会被覆盖;
  • 在静态方法中;
  • 在非静态方法中;
  • 在内部静态和非静态、本地和匿名类中。

47.什么是匿名类?

匿名类是没有自己的类型的类。我在说什么?当我们谈论接口时,我提到您不能创建接口对象:您只能创建实现该接口的类的对象。如果不想在类中实现接口,但仍需要接口类型的对象怎么办?最有可能的是,这将是使用该对象的单一情况。而且您不需要创建成熟的实现类。你将如何做到这一点?正确的!通过匿名课程!Java 开发人员访谈问答分析。 第 5 - 5 部分假设我们有一些Animal接口:
public final interface Animal {
   public void voice();
}
如果我们想通过匿名类实例化这个接口:
Animal cat = new Animal() {
   @Override
   public void voice() {
       System.out.println("Meow! Meow! Meow!");
   }
};
然后您就可以安全地使用这个对象及其实现的方法——语音。也就是说,匿名类此时此地实现该接口及其所有抽象方法。否则,我们将无法创建接口/抽象类对象,因为存在未实现/抽象方法。正如我提到的,匿名类不仅用于实现接口的抽象方法,还用于实现抽象类的抽象方法。这种方法适用于一次性使用对象或只需要一次给定方法实现的情况,并且不需要创建一个单独的类来实现所需的抽象类/接口。但我还要指出,在工作中很少使用匿名类:通常,仍然优先考虑普通类。您可以在本文中阅读有关匿名类的更多信息。

48.什么是原始类?

对我来说,这是一个非常奇怪的问题,也许这是一个陷阱问题,因为在 Java 中不存在原始类这样的东西:除了我们之前已经考虑过的原始类型的概念。我们记得,Java 中有 8 种基本类型:byteshortintlongfloatdoublecharbooleanJava 开发人员访谈问答分析。 第 5 - 6 部分

49.什么是“包装”类?

在 Java 中使用基本类型的主要问题是它们仍然不是类,并且 Java 仍然是一种 OOP 语言。也就是说,用这种语言编写的程序被简化为对象之间的交互。嗯,基元不是对象。它们没有方法,甚至没有Object类中的标准方法。那么,如果我们需要使用原语作为Map中的键怎么办?然后需要调用hashCode方法。您还可以在那里调用equals方法。然后怎样呢?在很多时候,应该有一个类,而不是一个原语,这使得原语在程序中成为未使用的和不需要的元素,因为这破坏了 OOP 的思想。但并非一切都像看起来那么糟糕。毕竟,Java 有原始包装器的概念。每个原始类型都有一个模拟类:
  • 字节->字节.class
  • ->短类
  • int ->整数类
  • ->长类
  • 浮动-> Float.class
  • ->双.class
  • 字符->字符.class
  • 布尔值-> Boolean.class
这是简单类型的表示,但以成熟的类的形式存在,具有一堆不同的函数方法。为了方便使用这些类,引入了自动装箱和拆箱的概念。 自动装箱- 必要时将原始类型自动转换为模拟类(例如,intInteger)。 拆箱是前一个过程的逆过程:自动将原始包装类转换为原始类型(例如,将Integer转换为int)。由于引入了原始包装类以及自动装箱拆箱过程,原始类型能够成为 OOP 语言 - Java 的成熟成员。Java 开发人员访谈问答分析。 第 5 - 7 部分要了解有关此主题的更多信息,我强烈建议阅读这篇文章

50.什么是嵌套类?什么时候使用?

嵌套类是一个内部类,它是另一个类的成员。在Java中,此类内部类有4种类型: 1. 内部类 这种类型的类直接在另一个类的主体中声明。嵌套内部类可以访问外部类实例的任何私有字段或方法。例如,让我们创建一个动物园,其中有一种动物 - 斑马:
public class Zoo {
   class Zebra {
       public void toFeed(String food) {
           System.out.println("Дать зебре - " + food);
       }
   }
}
没什么复杂的,对吧?我们来看一个创建内部类对象的例子:
Zoo.Zebra zebra = new Zoo().new Zebra();
zebra.toFeed("яблоко");
正如您已经看到的,必须创建框架类的对象,基于该对象的引用您可以创建内部类的对象。我还想指出,嵌套内部类不能有静态方法或静态字段。这是因为内部类与其外部类的对象隐式关联,并且内部类不能在其内部声明任何静态方法。 2. 静态嵌套类 该类与前一个类类似,只是它在类声明附近有一个static访问修饰符。由于这种类无法访问外部类的非静态字段,因此它更像是外部类的静态部分而不是内部类。在这种情况下,类数据可以访问外部类的所有静态成员,甚至是私有成员。静态嵌套类的示例:
public class Zoo {
   static class Zebra {
       public void toFeed(String food) {
           System.out.println("Дать зебре - " + food);
       }
   }
}
创建方法与之前略有不同:
Zoo.Zebra zebra = new Zoo.Zebra();
zebra.toFeed("яблоко");
这里我们不需要外部类的对象来创建嵌套静态类的对象。从外部类中,我们只需要它的类型,这样我们就可以找到嵌套类的位置。 3. 局部类 局部类是在方法体内声明的类,并且只能在该方法内创建和使用局部类的对象。例子:
public class Zoo {
   public void toFeed(String animal, String food) {
       switch(animal){
           case "зебра":
               class Zebra {
                   void toFeedZebra(String food) {
                       System.out.println("Дать зебре - " + food);
                   }
               }
               Zebra zebra = new Zebra();
               zebra.toFeedZebra(food);
               ...
使用示例:
Zoo zoo = new Zoo();
zoo.toFeed("зебра", "яблоко");
如果没有看到toFeed方法 的代码,您甚至不会怀疑本地类的存在,不是吗?局部类不能是static瞬态,但可以标记为abstractfinal(只能是OR,因为使用这两个修饰符会导致冲突)。 4. 匿名类 我们已经在上面讨论了匿名类,正如您所记得的,它们可以从两个来源创建:接口和类。 使用内部静态和非静态类的原因 是因为有时最好将小类嵌入到较大的类中并将它们保持在一起:这样它们将具有更高的内聚性和共同的目的。实际上,嵌套类的使用增加了代码封装性。选择局部类的原因可能是给定的类仅在单个方法中使用。在这种情况下,是否有必要将代码分散到整个应用程序中?不。但同时我要补充一点,在我的实践中我从未见过本地类的使用,因为 对它们的需求存在很大争议。嗯,使用匿名类的原因可能是接口或抽象类的特定实现只需要一次,因此不需要创建一个单独的、成熟的类及其实现。相反,我们以一种简单的方式,通过一个匿名类实现了我们需要的方法,使用了这个对象,然后忘记了它(好吧,垃圾收集器记住了它)。这篇文章和这篇Java 开发人员访谈问答分析。 第 5 - 8 部分文章将帮助您更详细地研究内部类。

51.类可以有哪些访问修饰符?

我们记得,有不同类型的类,并且适用于它们的访问修饰符也不同:
  • 外部类可以有访问修饰符public或没有修饰符(默认修饰符);
  • 内部类支持所有 4 个访问修饰符;
  • 嵌套静态类支持除protected之外的所有访问修饰符,因为 这个修饰符暗示着继承,这与类的静态成员相矛盾(静态元素不被继承);
  • 本地类只能有默认修饰符(即根本没有修饰符);
  • 匿名类:如果没有类类型声明,则根本没有访问修饰符。
这就是我们今天要停下来的地方。再见!Java 开发人员访谈问答分析。 第 5 - 9 部分
该系列其他材料:
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION