提交 fe28e4a0 编写于 作者: W wizardforcel

2020-06-13 15:42:05

上级 f28fba38
# Java – 创建不带“ new”关键字的对象
# Java – 不使用“`new`”关键字创建对象
> 原文: [https://howtodoinjava.com/puzzles/how-to-create-an-instance-of-any-class-without-using-new-keyword/](https://howtodoinjava.com/puzzles/how-to-create-an-instance-of-any-class-without-using-new-keyword/)
我们都知道如何创建任何类的对象。 在 Java 中创建对象的最简单方法是使用**新的**关键字。 让我们探讨一下 Java 中无需使用`new`新关键字即可创建对象的其他方法。
我们都知道如何创建任何类的对象。 在 Java 中创建对象的最简单方法是使用**`new`**关键字。 让我们探讨一下 Java 中无需使用`new`新关键字即可创建对象的其他方法。
```java
Table of contents
......@@ -15,9 +15,9 @@ Using reflection
```
> **注意:**在给定的示例中,我仅在编写伪代码。 要构建完整的,可以正常工作的示例代码,请阅读相关功能。
> **注意**:在给定的示例中,我仅在编写伪代码。 要构建完整的,可以正常工作的示例代码,请阅读相关功能。
## 使用 Class.newInstance()创建对象
## 使用`Class.newInstance()`创建对象
```java
Class ref = Class.forName("DemoClass");
......@@ -26,7 +26,7 @@ DemoClass obj = (DemoClass) ref.newInstance();
`Class.forName()`将类加载到内存中。 要创建此类的实例,我们需要使用`newInstance()`
## 使用类加载器的 loadClass()创建对象
## 使用类加载器的`loadClass()`创建对象
就像上述方法一样,类加载器的`loadClass()`方法执行相同的操作。 它使用相同类的现有实例创建类的新实例。
......@@ -34,7 +34,7 @@ DemoClass obj = (DemoClass) ref.newInstance();
instance.getClass().getClassLoader().loadClass("NewClass").newInstance();
```
## 使用 Object.clone()创建对象
## 使用`Object.clone()`创建对象
这也是拥有新的类的独立实例的方法。
......@@ -45,7 +45,7 @@ NewClass obj2 = (NewClass) obj.clone();
## 使用序列化和反序列化创建新对象
如果您已经阅读了本文 [](//howtodoinjava.com/java/serialization/how-to-do-deep-cloning-using-in-memory-serialization-in-java/ "How to do deep cloning using in memory serialization in java") ,则可以理解,序列化和反序列化也是在系统中拥有类的另一个实例的一种方式。
如果您已经阅读了[本文](//howtodoinjava.com/java/serialization/how-to-do-deep-cloning-using-in-memory-serialization-in-java/ "How to do deep cloning using in memory serialization in java"),则可以理解,序列化和反序列化也是在系统中拥有类的另一个实例的一种方式。
```java
ObjectInputStream objStream = new ObjectInputStream(inputStream);
......@@ -56,8 +56,7 @@ ObjectInputStream objStream = new ObjectInputStream(inputStream);
反射也是在大多数可用框架中创建新实例的流行方法。
builder.newInstance(); 或
class.newInstance();
`builder.newInstance();``class.newInstance();`
如果您认为我没有其他可能的方法,请告诉我。
......
此差异已折叠。
# Java 面试题目与答案
> 原文: [https://howtodoinjava.com/java-interview-puzzles-answers/](https://howtodoinjava.com/java-interview-puzzles-answers/)
这些 Java 题目及其答案将在您下一次 Java 编码面试中为您提供帮助。 提前了解他们的解决方案,以在您的下一次面试中留下更好的印象。
## Java 题目
* [Java 中的无效代码和无法访问的代码](//howtodoinjava.com/puzzles/dead-code-and-unreachable-code-in-java-puzzle/)
* [如何在不使用`new`新关键字](//howtodoinjava.com/puzzles/how-to-create-an-instance-of-any-class-without-using-new-keyword/)的情况下创建任何类的实例
* [检查回文数字](//howtodoinjava.com/puzzles/how-to-check-if-a-number-is-palindrome-in-java/)
* [如何检测 LinkedList](https://howtodoinjava.com/puzzles/how-to-detect-infinite-loop-in-linkedlist-in-java-with-example/) 中的无限循环
* [TreeMap 放置操作题目](//howtodoinjava.com/puzzles/java-puzzle-treemap-put-operation/)
* [查找所有不同的重复元素](//howtodoinjava.com/puzzles/java-puzzle-find-all-the-distinct-duplicate-elements/)
* [好的字符串 - 坏的字符串](//howtodoinjava.com/puzzles/java-puzzle-good-string-bad-string/)
* [检查字符串是否完整(包含所有字母)](//howtodoinjava.com/puzzles/puzzle-check-if-string-is-complete-contains-all-alphabets/)
* [返回所有具有第 N 个最长长度的字符串](//howtodoinjava.com/puzzles/puzzle-return-all-the-strings-with-the-nth-longest-length/)
* [如何反转字符串](//howtodoinjava.com/puzzles/how-to-reverse-string-in-java/)
* [从系列](//howtodoinjava.com/puzzles/find-missing-number-from-series/)中查找丢失的号码
如果被问到,别忘了分享更多这样的题目 – 并且您认为它们可以帮助其他人。
学习愉快!
\ No newline at end of file
......@@ -34,7 +34,7 @@ Frequently asked String Interview Questions
25\. Write a java program to reverse a string?
```
## 1\. Java 中的 String 关键字吗?
## 1\. Java 中的`String`是关键字吗?
没有。 `String`不是 Java 保留的关键字。 它是派生类型数据类型,即类。
......@@ -57,11 +57,11 @@ public class StringExample
这里的问题是为什么? 为什么一成不变? 让我们分析一下。
1. The very first reason i can think of is ***performance increase***. Java language was developed to speed up the application development as it was not that much fast in previous languages. JVM designers must have been smart enough to identify that real-world applications will consist of mostly Strings in form of labels, messages, configuration, output and such numerous ways.
1. 我能想到的第一个原因是***性能提升***。 开发 Java 语言是为了加快应用程序开发,因为以前的语言并没有那么快。 JVM 设计人员必须足够聪明,才能识别出现实世界中的应用程序将主要由标签,消息,配置,输出等多种形式的字符串组成。
看到这种过度使用,他们想像到不正确使用字符串会带来多大的危险。 因此,他们提出了字符串池的概念(下一部分)。 字符串池不过是一些大多数唯一字符串的集合。 字符串池背后的最基本思想是重新创建字符串。 这样,如果一个特定的字符串在代码中创建了 20 次,则应用最终将只有一个实例。
2. 第二个原因是 ***安全注意事项*** 。 字符串是 Java 编程各个方面中最常用的参数类型。 无论是加载驱动程序还是打开 URL 连接,您都需要以字符串形式将信息作为参数传递。 如果字符串不是最终的,那么它们就打开了一个安全问题的潘多拉盒。我们所有人都必须通过与 Java 中的 [String](https://docs.oracle.com/javase/8/docs/api/java/lang/String.html) 类相关的[面试问题](//howtodoinjava.com/java-interview-questions/)。 这些问题的范围从[不变性](https://en.wikipedia.org/wiki/Immutable_object#Java "immutability in java")到内存泄漏问题。 我将在这篇文章中尝试解决此类问题。
2. 第二个原因是***安全注意事项***。 字符串是 Java 编程各个方面中最常用的参数类型。 无论是加载驱动程序还是打开 URL 连接,您都需要以字符串形式将信息作为参数传递。 如果字符串不是最终的,那么它们就打开了一个安全问题的潘多拉盒。我们所有人都必须通过与 Java 中的[`String`](https://docs.oracle.com/javase/8/docs/api/java/lang/String.html)类相关的[面试问题](//howtodoinjava.com/java-interview-questions/)。 这些问题的范围从[不变性](https://en.wikipedia.org/wiki/Immutable_object#Java "immutability in java")到内存泄漏问题。 我将在这篇文章中尝试解决此类问题。
除了上述两个原因外,我没有找到任何令人信服的答案。 如果您有任何吸引人的内容,请与我分享。
......@@ -69,9 +69,9 @@ public class StringExample
字符串池是一个特殊的内存区域,与存储这些字符串常量的常规堆内存分开。 这些对象在应用的生命周期中称为字符串变量。
在 Java 中,可以通过多种方式创建 String。 让我们了解它们:
在 Java 中,可以通过多种方式创建`String`。 让我们了解它们:
#### 1)字符串分配
#### 1)字符串赋值
```java
......@@ -79,7 +79,7 @@ String str = "abc";
```
上面的代码使 JVM 验证是否已经有一个字符串“ abc”(相同的字符序列)。 如果存在这样的字符串,则 JVM 仅将现有对象的引用分配给变量`str`,否则,将创建一个新的对象“ abc”,并将其引用分配给变量`str`
上面的代码使 JVM 验证是否已经有一个字符串`"abc"`(相同的字符序列)。 如果存在这样的字符串,则 JVM 仅将现有对象的引用分配给变量`str`,否则,将创建一个新的对象`"abc"`,并将其引用分配给变量`str`
#### 2)使用`new`新关键字
......@@ -89,13 +89,13 @@ String str = new String("abc");
```
此版本最终**在内存**中创建两个对象。 字符串池中的一个对象具有 char 序列“ abc”,第二个对象在堆存储器中由变量`str`引用,并且具有与“ abc”相同的 char 序列。
此版本最终**在内存**中创建两个对象。 字符串池中的一个对象具有`char`序列`"abc"`,第二个对象在堆存储器中由变量`str`引用,并且具有与`"abc"`相同的`char`序列。
正如 java docs 所说的: ***除非需要显式的原始副本,否则不需要使用此构造器,因为字符串是不可变的。***
正如 java 文档所说的: ***除非需要显式的原始副本,否则不需要使用此构造器,因为字符串是不可变的。***
## 4.关键字“实习生”的用法
[java docs](https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#intern--) 最好地描述了这一点:
[java 文档](https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#intern--) 最好地描述了这一点:
调用`intern()`方法时,如果池已经包含一个与`equals(Object)`方法确定的等于`String`对象的字符串,则返回池中的字符串。 否则,将此`String`对象添加到池中,并返回对此`String`对象的引用。
......@@ -106,11 +106,11 @@ str.intern();
```
因此,对于`s``t`中的任何两个字符串,当且仅当`s.equals(t)``true`时,`s.intern() == t.intern()`才为`true`。 意味着如果 s 和 t 都是不同的字符串对象,并且具有相同的字符序列,则在这两个变量上调用 intern()将导致两个变量引用的单个字符串池文本。
因此,对于`s``t`中的任何两个字符串,当且仅当`s.equals(t)``true`时,`s.intern() == t.intern()`才为`true`。 意味着如果`s``t`都是不同的字符串对象,并且具有相同的字符序列,则在这两个变量上调用`intern()`将导致两个变量引用的单个字符串池文本。
## 5.匹配正则表达式
如果您还没有探索的话,它并不是那么秘密,但很有用。 您必须已经看到[模式](https://docs.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html "java util Pattern")和 Matcher 用于正则表达式匹配的用法。 字符串类提供了自己的快捷方式。 直接使用。 此方法还使用函数定义内的 *Pattern.matches()*
如果您还没有探索的话,它并不是那么秘密,但很有用。 您必须已经看到[`Pattern`](https://docs.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html "java util Pattern")`Matcher`用于正则表达式匹配的用法。 字符串类提供了自己的快捷方式。 直接使用。 此方法还使用函数定义内的`Pattern.matches()`
```java
......@@ -120,24 +120,24 @@ str.matches("<regex>");
```
## 6.使用 equals()和'=='进行字符串比较
## 6.使用`equals()`和`==`进行字符串比较
面试中另一个最喜欢的领域。 通常有两种比较对象的方法
* 使用==运算符
* 使用 equals()方法
* 使用`==`运算符
* 使用`equals()`方法
**`==`运算符比较对象引用**,即内存地址相等性。 因此,如果两个字符串对象引用字符串池中的相同文本或堆中的相同字符串对象,则`s==t`将返回`true`,否则返回`false`
`equals()`方法在 String 类中被覆盖,**它验证字符串对象**持有的 char 序列。 如果它们存储相同的字符序列,则 s.equals(t)将返回 true,否则返回 false
`equals()`方法在`String`类中被覆盖,**它验证字符串对象**持有的`char`序列。 如果它们存储相同的字符序列,则`s.equals(t)`将返回`true`,否则返回`false`
## 7.内存泄漏问题
到目前为止,我们已经完成了基本的工作。 现在发生了严重的事情。 您是否尝试过从字符串对象创建子字符串? 我敢打赌,是的。 您知道 Java 中子字符串的内部吗? 他们如何造成内存泄漏?
Java 中的子字符串是使用方法`substring(int beginIndex)`和此方法的其他一些重载形式创建的。 所有这些方法都会创建一个新的 String 对象,并更新在本文开头看到的 offset 和 count 变量。
Java 中的子字符串是使用方法`substring(int beginIndex)`和此方法的其他一些重载形式创建的。 所有这些方法都会创建一个新的`String`对象,并更新在本文开头看到的`offset``count`变量。
*原始值[]不变。 因此,如果您创建一个包含 10000 个字符的字符串,并创建 100 个每个包含 5-10 个字符的子字符串,则所有 101 个对象将具有大小为 10000 个字符的相同字符数组。 毫无疑问,这是内存浪费。*
*原始值数组不变。 因此,如果您创建一个包含 10000 个字符的字符串,并创建 100 个每个包含 5-10 个字符的子字符串,则所有 101 个对象将具有大小为 10000 个字符的相同字符数组。 毫无疑问,这是内存浪费。*
让我们使用程序来看看:
......@@ -178,7 +178,7 @@ java
```
显然,两个对象都存储有相同的 char 数组,而 subString 只需要四个字符。
显然,两个对象都存储有相同的`char`数组,而`subString`只需要四个字符。
让我们使用自己的代码解决此问题:
......@@ -228,9 +228,9 @@ java
现在,子字符串只有它需要的字符,并且可以无用地收集用于创建正确子字符串的中间字符串,从而不占用任何内存。
## 8\. String 如何在 Java 中工作?
## 8\. `String`如何在 Java 中工作?
Java 中的字符串类似于任何其他编程语言,都是字符序列。 这更像是用于该 char 序列的工具类。 此 char 序列在以下变量中维护:
Java 中的字符串类似于任何其他编程语言,都是字符序列。 这更像是用于该`char`序列的工具类。 此`char`序列在以下变量中维护:
```java
/** The value is used for character storage. */
......@@ -271,7 +271,7 @@ public class StringExample
```
## 11.如何从 String 中删除或替换字符?
## 11.如何从`String`中删除或替换字符?
要替换或删除字符,请使用`String.replace()``String.replaceAll()`。 这些方法有两个参数。 第一个参数是要替换的字符,第二个参数是将放置在字符串中的新字符。
......@@ -294,7 +294,7 @@ System.out.println( originalString.replace("o", "") ); //hwtdinjava
```
## 12.如何使 String 大写或小写?
## 12.如何使`String`大写或小写?
使用`String.toLowerCase()``String.toUpperCase()`方法将字符串转换为小写或大写。
......@@ -324,7 +324,7 @@ System.out.println(blogName.equals(anotherString)); //true
## 14.我们可以在开关盒中使用 String 吗?
是的,自 Java7 起,您可以在`switch`语句中使用 [`String`类。在 Java7 之前,这是不可能的,您必须使用`if-else`语句才能实现类似的行为。](https://howtodoinjava.com/java7/string-class-is-supported-in-switch-statement-in-java-7/)
是的,自 Java7 起,您可以在`switch`语句中使用[`String`类](https://howtodoinjava.com/java7/string-class-is-supported-in-switch-statement-in-java-7/)。在 Java7 之前,这是不可能的,您必须使用`if-else`语句才能实现类似的行为。
```java
String number = "1";
......@@ -343,11 +343,11 @@ default:
```
## 15.编写一个程序以打印 String 的所有排列?
## 15.编写一个程序以打印`String`的所有排列?
排列是对字符的有序列表的元素进行重新排列,以使每个排列相对于其他排列都是唯一的。 例如,以下是字符串“ ABC”的排列 – ABC ACB BAC BCA CBA CAB
排列是对字符的有序列表的元素进行重新排列,以使每个排列相对于其他排列都是唯一的。 例如,以下是字符串“`ABC`”的排列 – `ABC ACB BAC BCA CBA CAB`
> 长度为`N`的字符串具有`N! (N Factorial)`排列。
> 长度为`N`的字符串具有`N!`(`N`的阶乘)个排列。
```java
import java.util.HashSet;
......@@ -430,7 +430,7 @@ System.out.println(finalString.toString()); //woh ot od ni avaj tod moc
## 17.如何在 Java 中拆分字符串?
使用[`String.split()`](https://howtodoinjava.com/java/string/4-ways-to-split-tokenize-strings-in-java/)方法可在给定正则表达式的匹配项附近中断给定字符串。 也称为基于定界符的 get **字符串令牌。**
使用[`String.split()`](https://howtodoinjava.com/java/string/4-ways-to-split-tokenize-strings-in-java/)方法可在给定正则表达式的匹配项附近中断给定字符串。 也称为基于定界符的获取**字符串令牌**
`split()`方法返回字符串数组。 数组中的每个字符串都是单独的标记。
......@@ -443,15 +443,15 @@ System.out.println(Arrays.toString(numArray)); //[1, 2, 3, 4, 5, 6, 7]
```
## 18.为什么用 Char 数组而不是 String 来首选 Char 数组来存储密码?
## 18.为什么用`Char`数组而不是`String`来首选`Char`数组来存储密码?
我们知道字符串存储在 Java 的常量池中。 一旦在字符串池中创建了一个字符串,它将一直保留在该池中,直到收集到垃圾为止。 这时,任何恶意程序都可以访问物理内存位置中的内存位置,也可以访问字符串。
如果我们将密码存储为字符串,那么它也将存储在 spring pool 中,并且在内存中的可用时间比要求的更长,因为垃圾收集周期是不可预测的。 这使得敏感的密码字符串**容易遭到黑客攻击和数据盗窃**
如果我们将密码存储为字符串,那么它也将存储在 spring 中,并且在内存中的可用时间比要求的更长,因为垃圾收集周期是不可预测的。 这使得敏感的密码字符串**容易遭到黑客攻击和数据盗窃**
使用后可以将 String 留空吗? 不,我们不可以。 我们知道,一旦创建了字符串,我们将无法对其进行操作,例如,您不能更改其内容。 字符串是最终的且不可变的。
使用后可以将`String`留空吗? 不,我们不可以。 我们知道,一旦创建了字符串,我们将无法对其进行操作,例如,您不能更改其内容。 字符串是最终的且不可变的。
但是 char 数组是可变的,使用后它们的内容可以被覆盖。 因此,您的应用应使用 char []存储密码文本,并在使用密码后,将数组内容替换为空白。
但是`char`数组是可变的,使用后它们的内容可以被覆盖。 因此,您的应用应使用`char[]`存储密码文本,并在使用密码后,将数组内容替换为空白。
```java
String password = "123456"; //Do not use it
......@@ -470,18 +470,18 @@ for(char c : passwordChars) {
是的,字符串是[线程安全的](https://howtodoinjava.com/java/multi-threading/what-is-thread-safety/)。 它们是不可变的,默认情况下,java 中所有不可变的实例都是线程安全的。
## 20.为什么 String 是 Java 中流行的 HashMap 键?
## 20.为什么`String`是 Java 中流行的`HashMap`键?
在 Java 中,必须在`Map`中使用的键是不可变的,并且应遵循`equals()``hashCode()`方法之间的约定。 `String`类满足这两个条件。
另外,String 类提供了许多有用的方法来比较,排序,标记化或小写。 在`Map`上执行 CRUD 操作时可以使用这些方法。 这使它成为在`Map`中使用而不是创建自己的类的非常有用的类。
另外,`String`类提供了许多有用的方法来比较,排序,标记化或小写。 在`Map`上执行 CRUD 操作时可以使用这些方法。 这使它成为在`Map`中使用而不是创建自己的类的非常有用的类。
## 21\. String,StringBuffer 和 StringBuilder 之间的区别?
## 21\. `String`,`StringBuffer`和`StringBuilder`之间的区别?
* `String`类表示字符序列,并提供了使用字符的有用方法。 字符串类实例是不可变的。 因此,每次使用字符串类执行字符串连接时,都会使用连接的字符串创建一个新对象。
* `StringBuilder` class is used to perform string concatenation operations in more memory efficient way. It internally maintains a `char array` and manipulate the content in this array only.
* `StringBuilder`类用于以更节省内存的方式执行字符串连接操作。 它在内部维护一个`char`数组并仅操作该数组中的内容。
执行完所有操作后需要获取完整的连接字符串时,它将创建一个具有字符数组内容的新 String
执行完所有操作后需要获取完整的连接字符串时,它将创建一个具有字符数组内容的新`String`
* `StringBuffer``StringBuilder`类非常相似。 唯一的区别是它是线程安全的。 所有方法都是`synchronized`
......@@ -520,7 +520,7 @@ String s3 = new String("howtodoinjava.com");
3. 第二条语句不会创建任何新对象,并且`s2`将引用与`s1`相同的字符串常量。
4. 第三条语句将在堆内存中创建一个新的字符串对象。
24.如何计算字符串中每个字符的出现次数?
## 24.如何计算字符串中每个字符的出现次数?
为了找到给定字符串中每个字符的出现次数,我们使用了`HashMap`,并将该字符作为键,并将其出现作为值。 每次出现新的字符时,我们将增加该字符的值。
......@@ -548,7 +548,7 @@ System.out.println(occurancesMap);
```
25.编写一个 Java 程序来反转没有 StringBuilder 或 StringBuffer 的字符串?
## 25.编写一个 Java 程序来不使用`StringBuilder`或`StringBuffer`反转字符串?
反转字符串的最佳方法肯定是`StringBuffer.reverse()``StringBuilder.reverse()`方法。 不过,面试官可能会要求您编写自己的程序,以检查您的技能水平。
......@@ -578,6 +578,6 @@ public class StringExample
```
我可以想到这些**常见的 String 面试问题**将为您的下一次面试提供帮助。 如果您还有其他关于`String`类的问题,请分享。
我可以想到这些**常见的`String`面试问题**将为您的下一次面试提供帮助。 如果您还有其他关于`String`类的问题,请分享。
学习愉快!
\ No newline at end of file
......@@ -77,7 +77,7 @@ Java 9 中的一些重要功能/ [更改是:](https://howtodoinjava.com/java9/
* API 中的 [Lambda 表达式](//howtodoinjava.com/java8/complete-lambda-expressions-tutorial-in-java/)支持
* [流 API](https://howtodoinjava.com/java8/java-streams-by-examples/)
* [功能接口](//howtodoinjava.com/java8/functional-interface-tutorial/)[默认方法](//howtodoinjava.com/java8/default-methods-in-java-8/)
* [函数式接口](//howtodoinjava.com/java8/functional-interface-tutorial/)[默认方法](//howtodoinjava.com/java8/default-methods-in-java-8/)
* [可选](//howtodoinjava.com/java8/java-8-optionals-complete-reference/)
* Nashorn – JavaScript 运行时,允许开发人员将 JavaScript 代码嵌入应用中
* Java 类型注释
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册