javase基础
java介绍
java特性
- 跨平台(平台-操作系统):原因:jvm(java虚拟机)事先在操作系统中安装对应版本的jvm,把java程序放到jvm中运行,使得相同的java程序在不同的操作系统上得到的结果是一样的,屏蔽了底层操作系统的差异性。(.java文件在JVM外部编译,把.class放入到JVM来运行)
java三大架构
- j2se(基础版) 提供了桌面服务以及小程序开发的解决方案
- j2ee(企业版) 提供了企业集中式开发的解决方案
- j2me(小型版) 提供了嵌入式开发的可能性
jdk1.是一个里程碑式的版本,javase,javaee,javame
搭建java语言环境
- jre(java运行时环境) :提供java运行环境
jre=jvm+运行类库 - jdk(java开发工具包):提供java程序的运行环境和开发环境
jdk=jre+kit(开发工具包)
.java文件(源文件) 编译时期(在检测语法问题)
.class文件 (字节码对象) 运行时期(检测java程序的逻辑问题)
人机交互的方式
- 图形界面
- 命令行模式
命令提示符查找方式:win+r输入cmd
环境变量(可以指定操作系统给的值)
java基础语法
java关键字
是在java中具有特殊含义的字符串
例如:const,goto
false,true,null是关键字(有争论)
标识符
在java中可以自定义的名称
组成范围:
1.各国常见文字
2.数字
3.特殊的符号,例如:下划线,$(慎用----内部类使用)
注:
- 标识符命名不能以数字开头
- 不能出现关键字
有符号的数
计算机上所有的数据在底层都是以二进制数据的补码形式来表示
原码:符号位表示1代表负数,0代表正数
正数的反码补码一致
负数的反码是1变为0,0变为1,负数的补码是在反码的最后+1.
绝大多小数都是无限二进制数
数据类型
限制数据的变化范围
基本数据类型(4类8种)
整数型:byte 1,int 4,short 2,long 8
浮点型: double 8 ,float 4
布尔型:true,false 2
字符型:char 2 0~65535
char c=‘中’;
文字转成底层数字–编码,文字转成底层数字的规则------码表(ASCII 占用一个字节,ISO8859-1 西欧码表 占用一个字节,BIG5 繁体中文,占用两个字节,GB2312(简体中文------占用两个字节),GBK国标码 占用两个字节),GBK(国码标 占用2个字节)-------unicode(编码体系 UTF-8占用3个字节),UTF-16(占用·两个字节)、UTF-32)
所有完整码表默认兼容西欧码表
转义字符:
符号 ASCII码 意义
\n 10 换行NL
\r 13 回车CR
\t 制表符空格
引用数据类型(类,接口,数组)
常量
程序运行过程中值不发生改变
被final修饰发变量是常量
字面值常量
整数、小数、字符、字符串、布尔、空
int i=1;
自定义常量
例如:final int a=1;
变量
- 存储单个数据的容器,是java中最小的容器
- 如果变量不被操作可以先不给值。
- byte,short ,char无论做任何操作都会类型提升为int
静态变量
类存放在方法区的静态常量池中,静态变量存储在方法区静态常量池的静态区
静态变量被所有的对象共享
变量类型 | 默认值 |
---|---|
int,byte,short,long | 0 |
char | 一个空格 |
float,double | 0.0 |
引用值(比如String) | null |
静态方法
- 类存放在方法区的静态常量池中,静态方法存储在方法区静态常量池的静态区
- 静态方法被调用加载到栈中执行
- 静态方法不能直接访问非静态信息,静态信息可以直接访问静态信息,非静态信息可以直接访问静态信息以及非静态信息
注意:局部变量必须赋值,因为局部变量不会有赋值,而成员变量会有赋值
常量存储的地方
1、局部变量存储在栈中(不会被初始化)
2、全局变量、静态变量(全局和局部静态变量)存储在静态存储区
3、new申请的内存是在堆中
4、字符串常量也是存储在静态存储区
父子类执行顺序
父类静态信息–子类静态信息—父类(构造代码块、成员变量)---------------父类构造方法-----子类(构造代码块、成员变量)-----子类构造方法
先是类级别再试对象级别,无论是哪个级别顺序都是先父后子
运算符
位运算符
针对二进制数据的补码形式做运算
& (按位与),| (按位或0),按位异或、按位取反、>>右移动
/*
操作& 遇见0则0,任意整数&1=1是奇数
00000000 00000000 00000000 00000010 int 2
00000000 00000000 00000000 00000011 int 3
00000000 00000000 00000000 00000010 int 3
操作| 遇见1则1
操做^ 相同则0,不同则1,一个整数和另外一个整数按位异或两次结果还是本身
*/
int d=2;
System.out.println(d & 3);
/*
利用按位异或,两个数交换位置
效率较高
*/
c=b^c;
b=c^b;
c=b^c;
System.out.println(c);
/*
位运算符
>>右移,如果是正数,右移几位就要在最左边补上几个0,如果是负数,右移几位就要在最左边补上几个1
<<左移,如果是无论正负,左移几位就要在最右边补上几个0
>>>无符号右移:无论正负数,右边移几位就要在最左边补上几个0
*/
//三元运算符 布尔表达式?表达式值1:表达式值2
//要求两个表达式值的类型可以不一样,但是要保证两个类型的最大范围在接收值的类型范围之内
String max=d>c?"a":"b";
位运算(移位)
2>>0-----------2
2>>1-----------1
2>>2-----------0
2>>32-----------2
2>>33-----------1
2>>64-----------2
2>>65-----------1
int类型数据。指定的移动位数需要对32进行取余得到的结果值才是底层真正移动的位数
如果是long类型数据,指定的移动位数需要对64进行取余得到的结果值才是底层真正移动的位数
byte,short,char都是int为底层。
switch语句
1.表达式支持byte,short,int,char,从jdk1.5开始支持枚举类型,从jdk1.7开始支持String类型
容器
数组
概念:存储多个相同类型的容器
// A code block
int[] arr=new int[3];
System.out.println(arr);
/*
[I@1b6d3586:数组地址位置
[:指的是容器类型
I:指的变量类型
*/
/*
//错误格式
int[] arr1;
//底层没有开辟空间,所以不能存储数据
arr1={5,6};
*/
java内存分区(重要)
栈(存储变量),(所有的方法加载到栈中执行)存储在栈中的数据使用完毕时立刻销毁。不会给定系统默认初始值
堆(存储对象),存储对象如果不再使用会在某个时刻通过系统进行回收,给定系统默认初始值。
方法区(面向对象):存储类的信息,在静态区会给静态变量给定系统默认初始值
本地方法栈:(本地方法(操作系统)区)
(CPU)寄存器(PC计数器):表示代码执行的指令
for循环
增强for循环是拷贝一层,然后加2,不改变原值。
// 遍历数组的第三种方式
System.out.println(Arrays.toString(arr));
数组的扩容
数组定义后长度无法改变
//数组的扩容:
//给定原数组的扩容
int[] arr1={1,2,3,4,5};
/*int[] arr2=new int[arr1.length*2];//确定新长度
//数组的复制
System.arraycopy(arr1,0,arr2,0,arr1.length);
//数组地址值的复制
arr1=arr2; */
arr1=Arrays.copyOf(arr1,arr1.length*2);
System.out.println(Arrays.toString(arr1));
return
两个功能:
结束当前方法体
返回值进行返回
关键字
面向对象
面向过程:关注的是代码的实现细节
面向对象:先把代码实现细节整合到对象中,只要找到对象就能拥有对象的功能
面向对象基于面向过程
- 类是对象的概括,对象是对类的具体实现
- 类是描述信息,描述的信息就是对象即将拥有特征和行为。
构造方法:
- 构建对象
- 属性初始化
- 支持重载
- 类中至少含有一个构造方法
本质是一种编程范式
this
this指的是当前对象
this可以调用构造方法,只能在首行使用,只能在构造方法中使用
this可以代表还没有创建的对象,可以代表刚创建的对象,可以代表正在使用的对象
// An highlighted block
class Person{
String name;
public Person(){}
public Person(String name){
//调用上面无参构造方法,只能在构造方法中使用
this();
}
}
构造代码块
在创建对象时优先构造方法执行
{
int i=1;
}
super
// An highlighted block
class A{
public A(){
}
public void eat(){}
}
class B extends A{
public B(){
//在首行使用
super();
System.out.println();
}
public B(int i){
//默认情况下我们所有的构造方法默认都含有一个super语句去调用父类无参构造
//如果父类没有提供无参构造,我们需要书写super有参语句去调用父类的无参构造
super();
System.out.println("有参构造");
}
}
final
public static void main(String[] args){
//final修饰的数据如果是基本数据类型的数据值不能改变
//final修饰的数据如果是引用类型那么地址值不能改变
final int[] arr={12,3,4};
//arr.length=10;//length属性被final修饰,所以数组一旦定义完成,数组长度无法改变
//成员变量是在对象创建的时候使用
//final修饰成员变量要求在创建对象完成之前给定属性初始值
//final 修饰静态变量,要在类加载完成之前进行初始化
//静态代码块可以对静态属性进行初始化
final static int a;
final int i;
//构造代码块一次就解决
{
i=1;
}
static {
a=1;
}
/*public FinalDemo() {
i = 1;
}
public FinalDemo(int a) {
i = 1;
}*/
//最终方法,不能重写,但是能重载
public final void m(){}
public final void m(int a){}
//最终类
//不能被别的类继承但是可以继承别的类
}
abstract
多个子类都对父类中的某个方法进行了不同程度的重写,父类的某个方法的方法体内书写任何内容都没有意义,所以可以吧某个方法中的方法体去掉并且加上abstrct关键字类修饰就变成抽象方法,抽象方法一定要重写,如果不想重写所有的抽象方法可以把普通类变成抽象类。
抽象类目的是延展类的继承结构
注意:
1.抽象类中不一定含有抽象方法
2.抽象类中可以定义属性和方法
3.抽象类中可以创建构造方法
4.抽象类中不能创建对象,底层创建对象是由其他编程语言来实现的,java获取不到,所以抽象类没有对象。
5.抽象方法不可以被private/static/final分别修饰
6.方法的重载只和方法名和参数列表有关系,于其他的修饰符和返回值都没有关系
多态
优点:
参数同一调用
解耦
向上造型-------------可以调用那些方法看父类
interface
接口---------本质不是类
目的:是给类注入更多的功能。
注意:
接口支持多实现
接口和接口之间支持多继承
接口不可以定义构造方法
接口不可以创建对象
接口里都是抽象方法
优点:约束和模板
类与类之间是单继承,(树状图)可以快速检测出两者之间的关系,可以在编译时期进行检查
类与接口之间是多实现(网状图不能快速检测出两者之间的关系,在编译时期不检查在运行时期检测是否有实现关系)
接口和抽象的区别
- 抽象类支持单继承,接口支持多继承,接口和实现类支持多实现
- 抽象类可以定义构造方法,接口不能定义构造方法
- 接口中的属性默认被public static final共同修饰,抽象方法默认被public abstact共同修饰
- 接口的目的是为了给实现类注入更多的功能,抽象类是为了延展类的继承结构
- 抽象类中可以不是抽象方法,接口中都是抽象方法(暂时)
内部类
类里再定义类
方法内部类
- 方法内定义类
- 不能被访问权限修饰符修饰
- 创建对象只能在本方法中创建
- 可以获取本方法中常量信息
package Inner;
import sun.plugin2.applet.context.InitialJNLPExecutionContext;
public class InnerDemo {
public static void main(String[] args) {
new Outer().m();
}
}
class Outer {
int j = 1;//1.8之后会默认在底层加上final表示常量
//1.8之前需要手动添加final才是常量
public void m() {
//方法内部类
//只能定义所有的非静态信息和静态常量
//方法内部类不能被四个访问权限修饰符修饰但是可以被final/abstract修饰
//方法内部类只能获取当前方法中的常量信息,不能修改起值
class Inner extends Object implements Cloneable{
static final int i1 = 1;
int i = 1;
public void n(){
System.out.println(j);
x();
}
}
Inner inner= new Inner();
inner.n();
}
public void x(){}
}
成员内部类
package Inner;
public class InnerDemo2 {
public static void main(String[] args) {
Outer2.Inner2 inner2=new Outer2().new Inner2();
inner2.n();
}
}
class Outer2{
int k=1;
//成员内部类
//可以正常的继承和实现
//可以获取外部类所有信息
//可以被访问权限修饰符修饰也可以被final/abstract修饰
class Inner2{
static final int i=2;
public void n(){
System.out.println(k);
}
}
}
静态内部类
package Inner;
import org.omg.CORBA.portable.ValueOutputStream;
public class InnerDemo3 {
public static void main(String[] args) {
Outer3.Inner3 inner3 = new Outer3.Inner3();
inner3.m();
}
}
class Outer3 {
static int i = 1;
static class Inner3 {
static int l = 1;
public void m(){
System.out.println(i);
}
}
}
匿名内部类
默认继承/实现接口,抽写抽象方法
不是最终类以及接口都可以具有匿名内部类的形式
匿名内部类只能使用一次常用于接口的参数传递或者是抽象类
接口里定义类默认被static修饰以及内部接口默认被static修饰
// An highlighted block
package interfaceDemo;
public class InterfaceDemo {
public static void main(String[] args) {
B b=new B(){
@Override
public void m(){
}
};
//接口也具有内部类
A a= new A() {
@Override
public void n() {
}
@Override
public void m() {
}
};
}
}
interface A{
public void n();
public void m();
}
abstract class B{
public abstract void m();
}
接口里再定义类
// An highlighted block
package interfaceDemo;
public class InterfaceDemo2 {
public static void main(String[] args) {
System.out.println(Outer.Innter3.j);
System.out.println(Outer.Innter2.i);
System.out.println(Outer.Innter2.Innter4.k);
}
}
interface Outer{
//默认被static修饰
class Innter2{
static int i=2;
interface Innter4{
static int k=4;
}
}
//默认被static修饰
interface Innter3{
int j=1;
}
}
垃圾回收机制
- 栈:使用完的内容立即清除(不会产生垃圾)
- 方法区:存储类的信息(有垃圾但是很少)
- 堆:使用完的对象等到某个时刻才进行回收(垃圾回收主要针对内存区域)
堆分为新生代和老生代,新生代分为伊甸园区和幸存区,每次创建新对象先存储在伊甸园区,系统针对这个区域进行一次扫描,如果发现新对象没有在使用就通知系统进行垃圾回收,如果新对象还在使用就新对象挪动到幸存区里,系统针对幸存区里这个群与进行的多次扫描,如果发现对象没有在使用就通知系统进行垃圾回收,如果发生对象仍然在使用就把对象挪动到老生代,系统针对老生代这个区域进行扫描,如果发现对象没有在使用通知系统进行垃圾回收。如果发现对象还在使用就存储在老生代。
回收器(ZGC)
回收算法