**
JAVA复习系列(一)
1.1 Java入门(基础概念与常识)
s://img-blog.csdnimg.cn/966fa52155704091b93291628f525b9b.png)
1.1.1Java语言的特点
- 简单易学(我一开始就学的Java,没学过C,是学的第一个编程语言,感觉还行)
- 面向对象(老三样:封装,继承,多态)
- 平台无关性(摆脱了平台的束缚,通过Java虚拟机实现了一次编译多方运行)
- 可靠性(这个我还没有啥感触)
- 安全性(同4,还没啥具体感触)
- 支持多线程(c++语言没有内置的多线程机制,它只能调用系统的多线程机制来设计多线程的程序,Java语言提供了多线程机制,方便了很多)
- 支持网络编程(java本身就是简化网络编程而诞生的)
- 编译与解释并存(通过JIT编译器,运行时编译,将热点代码(重复出现的)保存下来,下次直接调用)
1.1.2 JVM,JDK,JRE的关系
1.1.2.1 JVM(虚拟机)
Java 虚拟机(JVM)是运行 Java 字节码的虚拟机。
JVM 有针对不同系统的特定实现(Windows,Linux,macOS),目的是使用相同的字节码,它们都会给出相同的结果。
什么是字节码?采用字节码的好处是什么?
在 Java 中,JVM 可以理解的代码就叫做 字节码 (即扩展名为 .class 的文件),它不面向任何特定的处理器,只面向虚拟机。
Java 语言通过字节码的方式,在一定程度上解决了传统解释型语言执行效率低的问题,同时又保留了解释型语言可移植的特点。
所以 Java 程序运行时比较高效,
而且,由于字节码并不针对一种特定的机器,因此,Java 程序无须重新编译便可在多种不同操作
系统的计算机上运行。(也就是实现了平台无关性)
Java 程序从源代码到运行一般有下面 3 步:
.java文件(源文件) 经过JDK中的javac编译变为**.class文件**(JVM可以理解的Java字节),再通过JVM,变成机器可以理解的二进制代码。
1.1.2.2 JRE与JDK
JRE 是 Java 运行时环境,它是运行已编译 Java 程序所需的所有内容的集合。
包括 Java 虚拟机(JVM),Java 类库,java 命令和其他的一些基础构件。
但是,它不能用于创建新程序。
JDK 是 Java Development Kit,它是功能齐全的 Java SDK。
它拥有 JRE 所拥有的一切,还有编译器(javac)和工具(如 javadoc 和 jdb)。
它能够创建和编译程序。
一句话:
只运行Java程序,只要电脑有JRE的环境就行了,若是想进行系统的编程就要有JDK进行支持。
但这并不是绝对的,如果是用JSP部署的web应用程序,也需要JDK中的编译器(javac)。
因为在应用程序服务器上运行Java程序的时候,应用程序服务器会将JSP转换成Java servlet,因此需要编译servlet。
1.1.3 Java与C++的区别?
这是一个我学习时比较疑惑的地方,学完了Java再学C++,整体上看,都是面向对象的语言,操作模式差不多,但细分后,才能发现一些实现过程中的区别。
1.最明显的区别是Java中彻底移除了指针,我压根儿就没有这玩意儿,安全的一批。
但相对的,C++中的指针功能确实很强大,也简单。
2.很直观的感受是,两者在继承方面有比较明显的区别。
Java是单继承,而C++可以多继承。
一个Java类只能有一个父类,有一个爹。
一个C++的类可以有好几个爹。
但Java中的接口可以多继承,达成了C++多继承的功能。
3.Java 有自动内存管理机制,不需要程序员手动释放无用内存。
(这个非常不错,省事)
4.在 C 语言中,字符串或字符数组最后都会有一个额外的字符‘\0’来表示结束。但是,Java 语言中没有结束符这一概念。
(学完Java再看c++的时候很懵,这个结束符显得有些多余,当然具体情况具体分析,我只是持个人意见吐槽一下,才疏学浅,孤陋寡闻了。)
1.1.4 应用程序主类和小程序主类的不同。
众所周知,Java中的主类指的是包含main()方法的类,一个程序可以有好多类,但主类只能有一个。
在Java应用程序中,主类不一定是一个公开类(用public修饰的),它是一个继承自系统类 JApplet 或 Applet 的子类。
而在小程序中,主类要求必须是 public 类,它是 Java 程序执行的入口点。
简单说应用程序是从主线程启动(也就是 main() 方法)。
applet 小程序没有 main() 方法,主要是嵌在浏览器页面上运行(调用 init() 或者 run() 来启动),嵌入浏览器这点跟 flash 的小游戏类似。
1.1.5 为什么说Java中解释与翻译并存?
Java 语言既具有编译型语言的特征,也具有解释型语言的特征,因为 Java 程序要经过先编译,后解释
两个步骤,由 Java 编写的程序需要先经过编译步骤,生成字节码(*.class 文件),这种字节码必须由Java 解释器来解释执行。因此,我们可以认为 Java 语言编译与解释并存。
1.1.2 Java语法
1.2.1. 字符型常量和字符串常量的区别?
1.样子上的区别
char 字符型常量,就是一个用单引号括起来的字符。
String 字符串,用双引号括起来的好几个字符或者一个。
2.存放上的区别
一个char字符存放的是一个整型值(ASCII值),可参加表达式运算。
一个String字符串存放的是内存地址值。
注意:一个字符型常量(char)占两个字节!
1.2.2 Java中常见的关键字
访问控制 | private | protected | public | ||||
---|---|---|---|---|---|---|---|
类,方法和变量修饰符 | final | class | static | extends | implements | interface | native |
native | new | strictfp | synchronized | transient | volatile | ||
程序控制 | break | continue | return | do | while | if | else |
for | instanceof | switch | case | default | |||
错误处理 | try | catch | throw | throws | finally | ||
包 | package | import | |||||
基本类型 | int | short | long | char | string | boolean | byte |
float | true | false | null | double | |||
变量引用 | super | this | void | ||||
保留字 | goto | const |
1.2.3 return,continut,break关系
continue跳出循环一次,继续执行后面的循环
break跳出整个循环体,继续指向剩下的非循环代码
return结束代码。
1.2.4 Java中什么是泛型?
Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。
泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。
1.2.5 什么是泛型擦除?
Java中的泛型是伪泛型,因为在编译期间,所有的泛型信息会被擦掉,也就是泛型擦除现象
List<Integer> list=new ArrayList<>();
list.add(12);
list.add("a");//这里编译时会报错
//但是通过反射添加,是可以的
Class<? extends List> clazz = list.getClass();
Method add = clazz.getDeclaredMethod("add", Object.class);
add.invoke(list, "kl");
System.out.println(list);
1.2.6 泛型的运用。
泛型一般有三种使用方式:泛型类、泛型接口、泛型方法
//此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型
//在实例化泛型类时,必须指定T的具体类型
public class Generic<T>{
private T key;
public Generic(T key) {
this.key = key;
}
public T getKey(){
return key;
}
}
1.2.7.1 如何实例化泛型类?
Nums<Integer> nums= new Nums<Integer>(123456);
1.2.7.2 泛型接口:
public interface Nums<T> {
public T method();
}
//实现泛型接口,不指定类型的情况:
class NewNums<T> implements Nums<T>{
@Override
public T method() {
return null;
}
}
//实现泛型接口,指定类型的情况:
class NewNums<T> implements Nums<String>{
@Override
public String method() {
return "hello";
}
}
1.2.7.3 泛型方法:
public static < E > void printArray( E[] nums)
{
for ( E e : nums){
System.out.printf( "%s ", e);
}
System.out.println();
}
1.2.7.4 常用泛型通配符:
1.? 表示不确定的 java 类型
2.T (type) 表示具体的一个java类型
3.K V (key value) 分别代表java键值中的Key Value
4.E (element) 代表Element
1.2.8 equals()方法。
一般来说,判断字符或字符串类型的两个数据是否相等的时候要用到equals()方法,==比较的是两者的数值,如果等号两边是引用变量则比较两者的地址值,父类(object)中的.equals()比较的是对象引用地址值,String或(类)中的equals()方法比较的是对象内容的值。
public class test1 {
public static void main(String[] args) {
String a = new String("ab"); // a 为一个引用
String b = new String("ab"); // b为另一个引用,对象的内容一样
String aa = "ab"; // 放在常量池中
String bb = "ab"; // 从常量池中查找
if (aa == bb) // true
System.out.println("aa与bb的内容相同");
if (a == b) // false,非同一对象
System.out.println("a与b是一个对象");else {
System.out.println("a与b不是一个引用对象");
}
if (a.equals(b)) // true
System.out.println("a与b两对象的内容相同");
if (42 == 42.0) { // true
System.out.println("两者内容相同");
}
}
}
出现这类情况的原因,主要是类覆盖了equals()方法,才使得该方法比较的是两者的内容,如果没有覆盖掉,那就是调用的object中的euqals()方法,那个父类中的equals()方法比较的是引用对象而不是他们的内容。
说明:
1.String 中的 equals 方法是被重写过的,因为 Object 的 equals 方法是比较的对象的内存地址,而 String 的 equals 方法比较的是对象的值。
2.当创建 String 类型的对象时,虚拟机会在常量池中查找有没有已经存在的值和要创建的值相同的对象,如果有就把它赋给当前引用。如果没有就在常量池中重新创建一个 String 对象。
1.2.9 hashCode()与equals()方法。
这是一个面试官经常问道的问题。
hashCode():
hashCode() 的作用是获取哈希码,也称为散列码;它实际上是返回一个 int 整数。
这个哈希码的作用是确定该对象在哈希表中的索引位置。
hashCode() 定义在 JDK 的 Object 类中,这就意味着 Java 中
的任何类都包含有 hashCode() 函数。另外需要注意的是: Object 的 hashcode 方法是本地方法,
也就是用 c 语言或 c++ 实现的,该方法通常用来将对象的 内存地址 转换为整数之后返回。
public native int hashCode();
散列表存储的是键值对(key-value),它的特点是:能根据“键”快速的检索出对应的“值”。
这其中就利用到了散列码!(可以快速找到所需要的对象)
注意:
如果两个对象相等,则 hashcode 一定也是相同的。两个对象相等,对两个对象分别调用 equals 方法都返回 true。
但是,两个对象有相同的 hashcode 值,它们也不一定是相等的 。
因此,equals 方法被覆盖过,则 hashCode 方法也必须被覆盖。
1.2.10 方法重载与重写。
额,这一部分我比较熟,所以复习的时候就不想写了,单纯记录一下这个知识点。