以下几个知识点是非常容易搞混的Java知识点。不准开编译器,并且先不看答案,要是能全部答对,那Java基础是挺牢固的。如果答对了,还能分析出具体原因,那算你NB。
一、关于Switch
代码:
- public class TestSwitch {
-
public static void main(String[] args) {
-
int i = 2;
-
switch (i) {
-
case 1:
-
System.out.println(1);
-
case 2:
-
System.out.println(2);
-
case 3:
-
System.out.println(3);
-
default:
-
System.out.println(4);
- }
- }
- }
public class TestSwitch {
public static void main(String[] args) {
int i = 2;
switch (i) {
case 1:
System.out.println(1);
case 2:
System.out.println(2);
case 3:
System.out.println(3);
default:
System.out.println(4);
}
}
}
结果:
2
3
4
分析:
少了break;所以2以下的case和default都执行了一遍。
二、Equals和==运算符
代码:
- public static void test() {
-
String x = "hello";
-
String y = "world";
-
String z = new String("helloworld");
-
String a = "helloworld";
-
System.out.println("x+y equals z:" + (x + y).equals(z));
-
System.out.println("a == z:" + (a == z));
-
System.out.println("x == hello:" + (x == "hello"));
-
System.out.println("a == helloworld:" + (a == "hello" + "world"));
-
System.out.println("a == x+y:" + (a == (x + y)));
- }
public static void test() {
String x = "hello";
String y = "world";
String z = new String("helloworld");
String a = "helloworld";
System.out.println("x+y equals z:" + (x + y).equals(z));
System.out.println("a == z:" + (a == z));
System.out.println("x == hello:" + (x == "hello"));
System.out.println("a == helloworld:" + (a == "hello" + "world"));
System.out.println("a == x+y:" + (a == (x + y)));
}
结果:
x+y equals z:true
a == z:false
x == hello:true
a == helloworld:true
a == x+y:false
分析:
1.String.equals()方法比较的是字符串的内容,所以(x + y).equals(z)为true.
2.“==”比较的是 String 实例的引用,很明显 a 和z 并不是同一个 String 实例,所以(a == z)为false.
3.根据常量池的知识,容易得知(x == "hello")和(a == "hello" + "world")都为true.
(常量池指的是在编译期被确定并被保存在已编译的.class 文件中的一些数据。它包含了
关于方法、类、接口等,当然还有字符串常量的信息。也就是所谓的持久代。)
4.那么(a == (x + y))为什么是false呢?这点暂点有点不大清楚。初步认为是x+y是引用相加,不能放入常量池。
三、Override覆盖
代码:
- public class Parent {
-
-
public static String say() {
-
return "parent static say";
- }
-
-
public String say2() {
-
return "parent say";
- }
- }
-
-
public class Child extends Parent {
-
public static String say() {
-
return "child static say";
- }
-
-
public String say2() {
-
return "child say";
- }
- }
-
-
-
-
-
-
public class OverrideTest {
-
-
public static void main(String[] args) {
-
Parent p = new Child();
- System.out.println(p.say());
- System.out.println(p.say2());
-
- }
-
- }
public class Parent {
public static String say() {
return "parent static say";
}
public String say2() {
return "parent say";
}
}
public class Child extends Parent {
public static String say() {
return "child static say";
}
public String say2() {
return "child say";
}
}
/**
* @author 子弹哥
*
*/
public class OverrideTest {
public static void main(String[] args) {
Parent p = new Child();
System.out.println(p.say());
System.out.println(p.say2());
}
}
结果:
parent static say
child say
分析:
1.我们创建了一个Parent类的实例。变量 p 的数据类型为 Parent 类 但是它仍旧是 Child 类的一个实例。因为Child类覆盖了Parent类的方法say2(),所以p.say2()调用为子类的方法。
2.为什么p.say()却是调用父类Parent的方法呢?因为Java中规定“实例方法被覆盖,静态方法被隐藏”.
关于Override的一些规则:
用子类的静态方法隐藏父类中同样标识的实例方法是不合法的,编译器将会报错;
用子类的实例方法覆盖父类中同样标识的静态方法也是不合法的,编译器同样会报错;
带关键字 final的方法(静态和实例方法)都不能被覆盖;
实例方法能够被覆盖;
抽象方法必须在具体类中被覆盖。
四、Java强类型
代码:
-
-
-
-
-
public class Type {
-
-
public static void main(String[] args) {
-
double i = 5.0;
-
double j = 1 / 4 + 3 / 4 + i + 12 / 6.0 + 3 / 4 + 1 / 4;
- System.out.println(j);
- }
-
- }
/**
* @author 子弹哥
*
*/
public class Type {
public static void main(String[] args) {
double i = 5.0;
double j = 1 / 4 + 3 / 4 + i + 12 / 6.0 + 3 / 4 + 1 / 4;
System.out.println(j);
}
}
结果:
7.0
分析:
Java 是强类型的 strongly type,它支持8 种基本数据类型。通过对这些基本数据类型用法的严格检查 Java 编译器能够及时地在开发过程中捕捉到许多简单细微的错误。基本数据类型的转换可以隐性地发生,所以转换时会有精度损失。由于1/4和3/4发生隐性类型转换,精度损失,不会生成0.25和0.75,所以有分号的数都为0。
五、假构造函数
代码:
-
-
-
-
-
public class Constructor {
-
-
private int a, b, c;
-
-
public void Constructor() {
-
a = 3;
-
b = 5;
- c = a + b;
- }
-
-
public void test() {
-
System.out.println("The value of c :" + c);
- }
-
-
public static void main(String[] args) {
-
Constructor c = new Constructor();
- c.test();
- }
- }
/**
* @author 子弹哥
*
*/
public class Constructor {
private int a, b, c;
public void Constructor() {
a = 3;
b = 5;
c = a + b;
}
public void test() {
System.out.println("The value of c :" + c);
}
public static void main(String[] args) {
Constructor c = new Constructor();
c.test();
}
}
结果:
The value of c :0
分析:
public void Constructor()并不是一个真正的构造函数,而是一个方法。所以c的值为默认值0.
六、提前引用
代码:
-
-
-
-
-
public class ForwardReference {
-
-
static int first = test();
-
static int second = 2;
-
-
static int test() {
-
return second;
- }
-
-
public static void main(String[] args) {
-
System.out.println("first = " + first);
- }
-
- }
/**
* @author 子弹哥
*
*/
public class ForwardReference {
static int first = test();
static int second = 2;
static int test() {
return second;
}
public static void main(String[] args) {
System.out.println("first = " + first);
}
}
结果:
first = 0
分析:
由于在初始化second之前test方法就访问了它,那么方法得到的是second的默认值,即 0。 因此输出结果first= 0,而不是2。假如你使用方法调用来初始化静态变量,那么你必须保证 这些方法并不依赖于在它们之后声明的其它静态变量。静态变量以及静态初始化块是在类被加载进 JVM 时执行初始化操作的。Java 语言规范8.5节指出“静态初始化块和静态变量是按照其在代码中出现的顺序依次执行初始化操作的,而不能在类变量声明出现之前就引用它”。
七、对象引用
代码:
-
-
-
-
-
public class TestRef {
-
-
public static void main(String[] args) {
-
StringBuffer a = new StringBuffer("a");
-
StringBuffer b = new StringBuffer("b");
- append(a, b);
-
System.out.println(a.toString() + "," + b.toString());
- b = a;
-
System.out.println(a.toString() + "," + b.toString());
- }
-
-
public static void append(StringBuffer a, StringBuffer b) {
- a.append(b);
- b = a;
- }
- }
/**
* @author 子弹哥
*
*/
public class TestRef {
public static void main(String[] args) {
StringBuffer a = new StringBuffer("a");
StringBuffer b = new StringBuffer("b");
append(a, b);
System.out.println(a.toString() + "," + b.toString());
b = a;
System.out.println(a.toString() + "," + b.toString());
}
public static void append(StringBuffer a, StringBuffer b) {
a.append(b);
b = a;
}
}
结果:
ab,b
ab,ab
分析:
大家来分析一下这题,我还没有完全理解。
我的分析,可能是错的,哈哈,算是抛砖引玉。
1.a.append(b);-->ab 。因为a是引用,所以调用a的方法,相当于直接调用jvm中的a,所做的append也相当于直接在对象上操作,生效。
2.append方法中第一次b=a,-->b。因为a,b都为main方法内局部变量,跨append方法作用域b对a的引用不生效。
3.main方法中第二次b=a,-->ab。因为在同一作用域方法中,b对a的引用生效,。
分享到:
相关推荐
在Java编程语言中,有一些知识点非常容易混淆,特别是在面试中...了解并理解这些容易混淆的Java知识点对于编写高质量的代码和成功通过面试至关重要。在实际编程中,应特别注意这些细节,以避免潜在的错误和意外行为。
以下是根据提供的文件信息,深入解析Java初学者容易混淆的知识点: ### 1. main()方法的语法格式 `public static void main(String[] args)`是Java应用程序的入口点。这里的`public`表示方法可被任何类访问,`...
本篇文章将深入探讨在Java学习过程中的一些关键知识点和容易混淆的概念。 基础篇: 1. JDK常用的包:Java Development Kit (JDK) 包含了Java运行环境和开发工具,其中核心的几个包如`java.lang`, `java.util`, `...
以下几点是初学者容易混淆的问题,详细解析如下: ### 1. String与StringBuffer的区别 #### 知识点详解: `String`和`StringBuffer`都是用于处理字符串的类,但它们之间存在显著差异。 - **String**:它是不可变...
这里记录本人学习java时经常记不住或有误区、或易混淆的知识点记录
北大青鸟S1考试题,做了下十几套卷子,把一些我认为比较混淆和重要以及我错误的题目摘了出来,加入了自己的分析
### 学习Java时自己整理的知识点 4 在深入探讨Java编程语言的过程中,我们会遇到很多易混淆的概念。本文将基于“学习Java时自己整理的知识点 4”这一主题,详细解析作者提到的关键知识点——`equals`方法与“==”...
在这个框架中,有些概念容易引起混淆,下面将详细解释其中的一些关键知识点。 (一)`Collection`与`Collections` `Collection`是Java集合框架的顶级接口,它定义了集合的基本行为,比如添加、删除、查找元素等。...
本压缩包包含的资源专注于这个主题,让我们详细了解一下相关知识点。 首先,Java混淆是针对Java字节码进行的一种优化技术,其目的是使得Java代码变得难以阅读和理解,从而提高代码的安全性。主要的工具是ProGuard,...
### JAVA混淆编译工具知识点详解 #### 一、概述 在现代软件开发中,随着Java语言的广泛应用,代码安全成为了不容忽视的问题。为了保护源代码不被轻易逆向工程或非法复制,开发者们通常会采用一种名为“混淆编译”的...
Java混淆是一种保护应用程序源代码安全的技术,通过将原始的可读性强的代码转换为难以理解的形式,以此来防止恶意用户逆向工程分析。Jock是一个常见的Java混淆工具,它的目标是使得Java字节码变得难以理解和调试。在...
Java是一种广泛使用的面向对象的编程语言,其语法严谨且具有丰富的功能。在Java中,注释是用来解释代码...通过理解和熟练运用这些Java基础知识,可以编写出结构清晰、可读性强的代码,为后续的编程学习打下坚实的基础。
知识点3:基于Java的代码混淆算法研究 基于Java的代码混淆算法研究是代码混淆技术研究的重要方向之一。Java是一种广泛使用的编程语言,基于Java的代码混淆算法可以保护Java软件的知识产权。研究表明,基于Java的...
### 学习Java时自己整理的知识点_3 在Java的学习过程中,经常会遇到一些容易混淆的概念,例如方法重载(overload)与方法重写(override),以及如何正确使用`super`关键字等。下面将对这些概念进行详细的解析,...
在本项目中,我们讨论的是一个使用Java编程语言编写的记忆测试小游戏,它是一个拼图游戏,具有不同的难度等级。这款游戏旨在通过娱乐的方式提升玩家的记忆力,适合各个年龄段的用户。接下来,我们将深入探讨Java编程...
在Java编程语言中,存在许多容易被忽视或者混淆的关键知识点,这些知识点往往在面试中会被重点考察。以下是一些核心的Java盲点及其详细解释: 1. **字符串操作与性能** - `String` 类型在Java中是不可变的,意味着...
本文将深入探讨Java反编译的相关知识点,包括为什么要使用反编译工具、常用的Java反编译工具以及如何使用这些工具。 首先,我们需要了解Java的编译过程。Java源代码(.java文件)通过Java编译器(javac)被编译成...
Jackson 是一个 Java 用来处理 JSON 格式数据的类库,性能非常好。 哈希计算工具 java-hash 用来计算 MD5、SHA 哈希算法的 Java 类库,支持 "MD5", "SHA", "SHA-1", "SHA-256", "SHA-384", "SHA-512". 高性能RPC...