Java基础06
Java基础面
什么是jvm jre jdk?
- JVM是Java Virtual Machine(Java虚拟机)的缩写,它是整个Java实现跨平台的最核心的部分,所有的java程序会首 先被编译为.class的类文件,这种类文件可以在虚拟机上执行,JVM的主要工作是解释自己的指令集 (即字节码)到CPU的指令集或对应的系统调用,保护用户免被恶意程序骚扰。 JVM对上层的Java源文件是不关心 的,它关注的只是由源文件生成的类文件(.class文件)。
- JRE是java runtime environment(java运行环境)的缩写。光有JVM还不能让class文件执行,因为在解释class的时候 JVM需要调用解释所需要的类库lib。在JDK的安装目录里你可以找到jre目录,里面有两个文件夹bin和lib,在这里可以 认为bin里的就是jvm,lib中则是jvm工作所需要的类库,而jvm和lib和起来就称为jre。
- JDK是java development kit(java开发工具包)的缩写。每个学java的人都会先在机器上装一个JDK,那 让我们看一 下JDK的安装目录。在目录下面有六个文件夹、一个src类库源码压缩包、和其他几个声明文件。其中,真正在运行 java时起作用的是以下四个文件夹:bin、include、lib、jre。现在我们可以看出这样一个关系,JDK包含JRE,而JRE 包含JVM。
jdk是JAVA程序开发时用的开发工具包,其内部也有JRE运行环境JRE。JRE是JAVA程序运行时需要的运行环境,就是说,如果你光是运行JAVA程序而不是去搞开发的话,只安装JRE就能运行已经存在的JAVA程序了
一幅图看懂八种基本数据类型
byte: 占用1个字节,取值范围-128 ~ 127
short: 占用2个字节,取值范围-215 ~ 215 -1
int:占用4个字节,取值范围-231 ~ 231 -1
long:占用8个字节
float:占用4个字节
double:占用8个字节
char: 占用2个字节
boolean:占用大小根据实现虚拟机不同有所差异
&和&& , |和||的区别和联系
-
& 称为逻辑与运算符,&& 称为短路与运算符,也可叫逻辑与运算符。 对于&:无论任何情况,&两边的操作数或表达式都会参与计算。 对于&&:当&&左边的操作数为false或左边表达式结果为false时,&&右边的操作数或表达式将不参与计算,此时最 终结果都为false。例如在验证用户登录时判定用户名不是null而且
不是空字符串,应当写为:username != null &&!username.equals(“”),二者的顺序不能交换,更不能用&运算符, 因为第一个条件如果不成立,根本不能进行字符串的equals比较,否则会产生NullPointerException异常。
-
&还可以用作位运算符。当&两边操作数或两边表达式的结果不是boolean类型时,&用于按位与运算符的操
作。
|和||的区别类比&和&&
基本数据类型转换
强制转换规则:
高级变为低级需要强制转换。
如何转换:
(1)赋值运算符“=”右边的转换,先自动转换成表达式中级别最高的数据类型,再进行运算。
(2)赋值运算符“=”两侧的转换,若左边级别>右边级别,会自动转换;若左边级别 == 右边级别,不用转换;若左 边级别 < 右边级别,需强制转换。
(3)可以将整型常量直接赋值给byte, short, char等类型变量,而不需要进行强制类型转换,前提是不超出其表述 范围,否则必须进行强制转换。
递归算法总结
public class Recursion { //阶乘算法
public int factorial(int num){
if (num==0 || num== 1){
return 1; }
else{
return num*factorial(num-1);
}
}
public static void main(String[] args) {
Recursion recursion = new Recursion();
int n = 0;
int factorial = recursion.factorial(n);
System.out.println(factorial);
}
}
-
递归就是在过程或函数里调用自身。
-
在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。
-
递归算法解题通常显得很简洁,但运行效率较低。所以一般不提倡用递归算法设计程序。
-
在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等。所以一般不提倡用递归算法设计程序。
java.lang.Object类的六个常用方法
(1)public boolean equals(java.lang.Object)比较对象的地址值是否相等,如果子类重写,则比较对象的内容是否相等;
(2)public native int hashCode() 获取哈希码
(3)public java.lang.String toString() 把数据转变成字符串
(4)public fifinal native java.lang.Class getClass() 获取类结构信息
(5)protected void fifinalize() throws java.lang.Throwable垃圾回收前执行的方法
(6)protected native Object clone() throws java.lang.CloneNotSupportedException 克隆
(7)public fifinal void wait() throws java.lang.InterruptedException多线程中等待功能
(8)public fifinal native void notify() 多线程中唤醒功能
(9)public fifinal native void notifyAll() 多线程中唤醒所有等待线程的功能
==和equals的区别和联系
“==”是关系运算符,equals()是方法,同时他们的结果都返回布尔值;
“==”使用情况如下:
a) 基本类型,比较的是值
b) 引用类型,比较的是地址
c) 不能比较没有父子关系的两个对象
equals()方法使用如下:
对于equals方法,在该方法未被重写时,其效果和==一致,但用户可以根据对应需求对判断逻辑进行改
写,比如直接比较对象某个属性值是否相同,相同则返回true,不同则返回false。需保证equals方法相
同对应的对象hashCode也相同。
谈谈Java的多态
实现多态的三个条件
-
继承的存在(继承是多态的基础,没有继承就没有多态)
-
子类重写父类的方法。(多态下会调用子类重写后的方法)
-
父类引用变量指向子类对象。(涉及子类到父类的类型转换)
向上转型 Animal a = new Cat();
将一个父类的引用指向一个子类对象,称为向上转型,自动进行类型转换。此时通过父类引用变量调用的方法是子类覆盖或继承父类的方法,而不是父类的方法,此时通过父类引用变量无法调用子类特有的方法
向下转型 Cat a2 = (Cat)a;
将一个指向子类对象的引用赋给一个子类的引用,成为向下转型,此时必须进行强制类型转换。向下转型必须转换为 父类引用指向的真实子类类型,否则将出现ClassCastException,不是任意的强制转换.
Integer与int的区别
- int是java提供的8种原始数据类型之一,Java为每个原始类型提供了封装类,Integer是java为int提供的封装类。
- int的默认值为0,而Integer的默认值为null,即Integer可以区分出未赋值和值为0的区别,int则无法表达出未赋值的 情况,例如,要想表达出没有参加考试和考试成绩为0的区别,则只能使用Integer。
- 在JSP开发中,Integer的默认为 null,所以用el表达式在文本框中显示时,值为空白字符串,而int默认的默认值为0,所以用el表达式在文本框中显示 时,结果为0,所以,int不适合作为web层的表单数据的类型。
同步代码块和同步方法有什么区别
相同点:
同步方法就是在方法前加关键字synchronized,然后被同步的方法一次只能有一个线程进入,其他线程等待。而同 步代码块则是在方法内部使用大括号使得一个代码块得到同步。同步代码块会有一个同步的“目标”,使得同步块更加 灵活一些(同步代码块可以通过“目标”决定需要锁定的对象)。一般情况下,如果此“目标”为this,那么同步方法和同 步代码块没有太大的区别。
区别:
同步方法直接在方法上加synchronized实现加锁,同步代码块则在方法内部加锁。很明显,同步方法锁的范围比较 大,而同步代码块范围要小点。一般同步的范围越大,性能就越差。所以一般需要加锁进行同步的时候,范围越小越 好,这样性能更好。
Java创建对象的几种方式
- 用new语句创建对象,这是最常见的创建对象的方法。
- 运用反射手段,调用java.lang.Class或者java.lang.reflflect.Constructor类的newInstance()实例方法。
- 调用对象的clone()方法。
- 运用反序列化手段,调用java.io.ObjectInputStream对象的 readObject()方法。
(1)和(2)都会明确的显式的调用构造函数 ;(3)是在内存上对已有对象的影印,所以不会调用构造函数 ;(4)是从文件中还原类的对象,也不会调用构造函数。
继承条件下构造方法的执行过程
情况1:如果子类的构造方法中没有通过super显式调用父类的有参构造方法,也没有通过this显式调用自身的其他构 造方法,则系统会默认先调用父类的无参构造方法。在这种情况下,写不写“super();”语句,效果是一样的。
情况2:如果子类的构造方法中通过super显式调用父类的有参构造方法,那将执行父类相应构造方法,而不执行父 类无参构造方法。
情况3:如果子类的构造方法中通过this显式调用自身的其他构造方法,在相应构造方法中应用以上两条规则。
特别注意的是,如果存在多级继承关系,在创建一个子类对象时,以上规则会多次向更高一级父类应用,一直到执行 顶级父类Object类的无参构造方法为止。
简述Java的垃圾回收机制
显示回收的缺点
-
程序忘记及时回收,从而导致内存泄露,降低系统性能。
-
程序错误回收程序核心类库的内存,导致系统崩溃。
垃圾回收机制,简称GC
- 可以提高编程效率。
- 保护程序的完整性。
- 其开销影响性能。Java虚拟机必须跟踪程序中有用的对象,确定哪些是无用的。
垃圾回收机制的特点
- 垃圾回收机制回收JVM堆内存里的对象空间,不负责回收栈内存数据。
- 对其他物理连接,比如数据库连接、输入流输出流、Socket连接无能为力。
- 垃圾回收发生具有不可预知性,程序无法精确控制垃圾回收机制执行。
- 可以将对象的引用变量设置为null,暗示垃圾回收机制可以回收该对象。
-
程序员可以通过System.gc()或者Runtime.getRuntime().gc()来通知系统进行垃圾回收,会有一些效果,但是系统是否进行垃圾回收依然不确定。
-
永远不要主动调用某个对象的fifinalize方法,应该交给垃圾回收机制调用。
接口和抽象类的区别
相同点
抽象类和接口均包含抽象方法,类必须实现所有的抽象方法 .
抽象类和接口都不能实例化,他们位于继承树的顶端,用来被其他类继承和实现
两者的区别主要体现在两方面:语法方面和设计理念方面 语法方面的区别是比较 低层次的,非本质的,
主要表现在:
接口中只能定义全局静态常量,不能定义变量。抽象类中可以定义常量和变量。
接口中所有的方法都是全局抽象方法。抽象类中可以有0个、1个或多个,甚至全部都是抽象方法。
抽象类中可以有构造方法,但不能用来实例化,而在子类实例化是执行,完成属于抽象类的初始化操作。接口中不能 定义构造方法
反射的概念与作用
作用
Java反射可以于运行时加载,探知和使用编译期间完全未知的类.
程序在运行状态中, 可以动态加载一个只有名称的类, 对于任意一个已经加载的类,都能够知道这个类的所有属性
和方法; 对于任意一个对象,都能调用他的任意一个方法和属性;
加载完类之后, 在堆内存中会产生一个Class类型的对象(一个类只有一个Class对象), 这个对象包含了完整的类的
结构信息,而且这个Class对象就像一面镜子,透过这个镜子看到类的结构,所以被称之为:反射.
java反射使得我们可以在程序运行时动态加载一个类,动态获取类的基本信息和定义的方法,构造函数,域等。
除了检阅类信息外,还可以动态创建类的实例,执行类实例的方法,获取类实例的域值。反射使java这种静态
语言有了动态的特性。
成员变量用static修饰和不用static修饰有什么区别?
1. 两个变量的生命周期不同。成员变量随着对象的创建而存在,随着对象的被回收而释放。 静态变量随着类的加载而存在,随着类的消失而消 失。
2. 调用方式不同。 成员变量只能被对象调用。 静态变量可以被对象调用,还可以被类名调用。
对象调用:p.country
类名调用 :Person.country
3,别名不同成员变量也称为实例变量。 静态变量称为类变量。
4,数据存储位置不同。成员变量数据存储在堆内存的对象中,所以也叫对象的特有数据. 静态变量数据存储在方法区(共享数据区)的静态区,所以也叫对象的共享数据.