java笔记

www.oracle.com//甲骨文官网下载jdk
java -version//查看Java版本
ipconfig//查看本机地址

poweshell与cmd的区别:
poweshell是面向对象的,cmd是面向过程的
cmd能做的powershell都能做,但比较早的windows没有powershell

%…%指的是你的系统安装的位置,
比如说如果你的系统装在C盘,“%ProgramFiles%\Windows Media Player\wmplayer.exe”
指的就是–>“C:\ProgramFiles%\Windows Media Player\wmplayer.exe”,
如果你的系统装在D盘,则表示为:“D:\ProgramFiles%\Windows Media Player\wmplayer.exe”
%SystemRoot%是windows文件夹的意思,因为系统安装的时候有可能是c盘,有可能是d盘,
编程时用这个可以直接找到windows文件夹,不需要知道系统安装到那个盘

javadoc命令:可以提取javadoc注释,生成帮助文档;
javadoc注释格式:
/**
* Javadoc注释
* Javadoc注释
* javadoc注释
*/

一 Java基础知识
1.常用dos命令:
exit 退出当前窗口
cls 清屏
dir 当前目录下的文件
cd 跳转到(路径)
cd… 目录上一级
cd\ 直接回到根路径
del *class 删除所有class文件

2.java三大块
	JavaSE		Java标准版(基础)
	JavaEE		Java企业版
	JavaME		Java微型版

3.Java语言特性
	简单性

	面向对象:纯面向对象语言
	
	可移植性:Java程序可以做到一次编译,到处运行。
		实现原理:Java其实是运行在一台虚拟机中,被称为JVM,Java虚拟机再和不同的运行平台打交道
				  Java虚拟机包含在JDK中,JDK是Java开发工具包,JDK中还包括JRE
				  jdk (Java development kits)java开发工具包
				  jvm (Java virtual machine)虚拟机
				  jre (java runtime environment)java运行时环境
				  JDK包括jre,jre包括jvm
				  jdk11以后就没有jre了
	
	多线程
	
	健壮性:与自动垃圾回收机制有关,简称GC机制(Java中在堆区开辟的空间释放不需要程序员关心,但c++需要手动释放)
	
	安全性

4.Java的加载与执行
	编译期:.java文件(源文件) -> .class文件(字节码文件):这个过程是编译过程,由JDK自带的javac.exe来执行编译,javac.exe被称为编译程序。
		使用方法:(DOS窗口中)javac  Java源文件的路径
		一个Java源文件可以生成多个.class文件  class文件生成后可以拷贝到别的操作系统运行(跨平台)

	运行期:java.exe负责运行阶段
			使用方法:java class类文件(不用后缀名)
			运行阶段过程:java A:java.exe命令会启动java虚拟机,jvm会启动类加载器ClassLoader
						classloader会去硬盘上搜索A.class文件,找到后会将该文件装载到JVM当中
						jvm将class字节码文件解释成二进制数据,然后os执行二进制和底层硬件平台进行交互

5.java的helloworld:
	public class helloworld//类名要与文件名一致
	{
		public static void main(String[] args){//String包要大写
			System.out.println("hello world");//System包要大写
			java.util.Scanner s = new java.util.Scanner(System.in)
		}
	}

二 Java程序的编译与执行
1.Java环境变量的配置
dos命令:
window操作系统是如何搜索硬盘上某个命令的呢?:
首先会从当前目录下搜索
当前目录搜索不到的话,会从环境变量path(系统变量)指定路径当中搜索某个命令
若都搜不到,则报错

2.编译 javac java文件路径(需要后缀名)

3.运行 java class文件(不要后缀名)
	java.exe会调用jvm,jvm会调用classloader,classloader会在硬盘上寻找字节码文件,找到后加载到jvm中去。
	但classloader是如何寻找的呢?

4.classloader原理
	-默认情况下,classloader从当前目录下加载字节码文件的
	-当然也可以让classloader去指定的路径下加载字节码文件,这时需要配置环境变量classpath
	-classpath是给classloader类加载器指路的。
	-设置这样的环境变量:classpath = d:\course\javaprojects\02-javase\day02
		-这样,打开dos命令窗口在任意位置,都可以执行java Helloworld

	-classpath环境变量没有配置的话,类加载器默认从当前路径下找字节码文件
	-当classpath环境变量配置为某个指定的路径之后,类加载器只去指定路径下加载class字节码文件
	-综上所述,环境变量classpath不再配置,这样类加载器会自动从当前路径下加载class字节码文件
	-所以每一次执行.class程序的时候,需要在dos命令窗口中先切换到.class字节码文件所在的路径下,然后运行

5.注释方法:
	5.1 单行注释://
	5.2 多行注释:/**/
	5.3 javadoc注释
		javadoc命令:可以提取javadoc注释,生成帮助文档;
		javadoc注释格式:
			/**
			*	Javadoc注释
			*	Javadoc注释
			*	javadoc注释
			*/

6.	一个Java源文件中可以定义多个类
	一个java源文件当中不一定有public class 
	一个class会定义生成一个字节码文件
	如果有public class ,则文件名与公共类的类名必须一致
	一个源文件中只能有一个公共类,但可以有多个类

	每个类中必须要有主方法public static void main(String[] args),否则会出现运行阶段错误

三 编程常识,不同语言编程通用知识
1.不能数字开头,严格区分大小写,关键字不能做标识符

2.标识符规范:
	见名知义
	遵守驼峰命名方式:	SystemService

	类名,接口名:首字母大写,后面每个单词首字母大写
	变量名,方法名:首字母小写,后面每个单词首字母大写
	常量名:全部大写

3.	ASCII码	'a' --> 97,'A' --> 65,'0' --> 48
	后来出现了一种编码方式统一了全球所有的文字,容量较大,这种编码方式叫做:unicode编码,
	unicode编码方式有多种具体实现:
	-UTF-8
	-UTF-16
	-UTF-32
	Java采用的是Unicode编码方式,实际开发中,一般使用UTF-8编码方式较多

4.println表示输出后换行,print表示输出后不换行,反斜杠\表示转义字符

5.JDK中自带的native2ascii.exe命令,可以将文字转换成Unicode编码形式,在dos命令下直接执行即可
	Unicode编码格式'\u4e2d',这个编码是"中"的意思,"\u"是unicode的意思

6.	int num = 10;//10进制
	int num = 010;//8进制
	int num = 0x10;//十六进制

7.	小容量转大容量自动类型转换
	大容量转小容量精度损失,需要强制类型转换,否则编译失败
	对于 long num = 2147483648;虽然long是8个字节可以存的下,但是Java在遇到数字时第一反应都是先当作int
	来处理,所以对于 long num = 2147483648;再把值赋值给 num之前就已经超过int的表示范围了,
	需要在数字后面加上L;

8.从键盘接受输入:
	java.util.Scanner s = new java.util.Scanner(System.in);
	int age = s.nextInt();

9. 引入包,类
	import java.util.Scanner;

四 方法
1.修饰符列表 返回值类型 方法名(形式参数列表){方法体;return;}

2.方法执行过程中的内存分配:
	jvm中分为:	方法区内存:存放的是字节码文件的代码片段,例如String类,
				栈内存:调入主方法,主方法内的局部变量内存都分配在主方法的栈区内存,
						然后主方法调用不同的方法。
				堆:new来开辟

3.方法重载

4.方法的递归调用

五 Java面向对象
1.面向对象三大特征:
封装,继承,与多态;

2.	面向对象的分析:OOA Object-oriented analysis;
	面向对象的设计:OOD Object-oriented design;
	面向对象的编程:OOP Object-oriented programming

3.	类的定义
	[修饰符列表] class 类名
	{
		//在类体中声明的变量如果不创建对象,它的内存空间是不存在的,只有创建了对象,才会为变量分配内存
		//成员变量没有赋值的话,系统默认赋值
		int num;
		
		//实例化对象的语法:new 类名();
		//new运算符的作用是创建对象,在jvm堆内存当中开辟新的内存空间
		//s 是引用,new出来的才是对象
		Student s = new student();
		//如下A==B,但C != D;
		//Java中,普通字符串存储在常量池中,常量池目前位于堆内存中,
		//所以,从赋值方面来看,此时的A==B是成立的,比较的是常量池里的值。
		String A="abc";
		String B="abc";
		String C=new String("abc");
		String D=new String("abc");
		
	}
	
4.	JVM主要包括三块内存空间,分别是栈内存,堆内存,方法区
	堆内存和方法区内存各有一个,一个线程一个栈内存。
	方法调用时,该方法所需空间在栈内存中分配。
	栈中主要存储的是方法中的局部变量
	方法的代码片段及整个类的代码片段都被存储在方法区中,在类加载时这些代码片段会载入
	使用 new 运算符创建Java对象,存储在堆内存中。
	变量分类:
		局部变量
		成员变量:
			实例变量:前面修饰符没有static,存放在堆内存
			静态变量:前面修饰符有static,存放在方法区内存当中
	三块内存当中变化最频繁的时栈内存,最先有数据的是方法区内存,GC主要针对堆内存
	当没有引用指向对象时,对象就无法被访问,成为垃圾对象,需要GC回收内存

5.空指针异常
	空引用访问实例相关数据,会引起空指针异常
	空引用访问实例相关方法,也会引起空指针异常
	
6.构造方法
	当一个类没有提供任何构造方法,系统会默认提供一个无参数的构造方法。(而这个构造方法被称为缺省构造器)
	Student s1 = new Student();//new后面调用的是构造方法
	//输出s1时会显示Student@54bedef2,就是这个对象的地址
	System.out.println(引用)
	System.out.println(引用.toString())
	//上面两个输出内容相同,都是  类名@十六进制哈希值

7.封装(保护数据,暴露接口)
	属性私有化 private :只能在本类中访问
	对外提供get和set方法
	对于set方法入口可以设置关卡,以免传入数据非法,比如年龄是负数非法;

8.static关键词
	带有static关键词的实例方法调用用 类名. 的方法来调用,也可以用引用调用,但实际还是类名.的方式
	不带static关键词的实例方法,用对象来调用
	只要方法调用就会压栈
	静态变量:前面修饰符有static,存放在方法区内存当中,静态变量在类加载时初始化
	可以通过引用来访问静态的成员变量,但不建议这样。
	//如果用空引用访问静态变量,不会出现空指针异常

	//使用static关键字可以定义静态代码块:
		static{
			Java语句;
			Java语句;
		}
	static静态代码块在类加载时执行,且只执行一次。
	 同一个类中的静态代码块顺序执行
	不同类中的静态代码块按照main方法中调用的顺序执行
	static声明的都是在同一时刻初始化的,按照先后顺序执行
	
	static静态代码块不常用,但可以给程序员一个时间点,叫做类加载时机。
	比如说要记录一些类加载的日志信息(什么时候什么类加载到jvm当中去了)
	
	//除了静态代码块,还有一种语句叫做:实例代码块,就是一对大括号
	{
		Java语句;
		Java语句;
	}
		每次实例化对象的时候,实例语句块都会在构造方法执行之前执行。

9.this关键词
	this是一个变量,是一个引用,this保存当前对象的内存地址,指向自身
	this存储在堆内存的对象当中
	this不能使用在静态方法中,哪个引用调用这个实例方法,this就是哪个引用

	this除了可以用在实例方法中,还可以用在构造方法中;
		通过当前的构造方法去调用另一个本类的构造方法,其语法是:
			public Date(){
				this(1970,1,1);//有点像方法重载,通过参数来选择其他构造方法;作用是:代码复用
			}
			public Date(int year,int month,int day){
				this.year = year;
				this.month = month;
				this.day = day;
			}
			//this()只能出现在构造方法中的第一句,且不能出现两次

10.继承extends
	语法:class 类名 extends 父类{}
	子类会继承父类中除构造方法外的所有东西,父类中的私有成员也能继承,只是在子类中无法直接访问
	子类继承父类后的访问权限只能变高,不能变低
	访问权限:public > protected > default > private 

	父类又称为基类,超类(superclass);
	子类(subclass)又称为派生类,扩展类;
	java不支持多继承,但可以间接继承

	Java中的类没有显示的继承任何类,则默认继承Object类,Object类是Java提供的根类。
	也就是说,一个类天然的继承了Object类中的所有特征.
	
	System.out.println();//System是一个类名,System.out说明out是一个静态变量
	//out.println()说明out是一个引用,println是一个实例方法

	当源码当中一个方法以分号结尾并且修饰符列表中有native关键字,
	表示底层调用c++写的dll程序,动态链接库

11.方法的覆盖与多态
	方法覆盖,子类覆盖父类方法;
		私有方法无法覆盖,调用的时候,引用是什么类型,就调用哪个方法
		构造方法无法继承,无法覆盖
		方法覆盖只是针对实例方法,静态方法覆盖无意义
		
		方法覆盖的返回值类型如果是基本数据类型,则必须一直,如果是引用数据类型,则可以大转小
		也就说,父类可以转为子类。
		class Test01
		{
			public Test01 doSome(){
				return null;
			}
		}
		class Test02 extends Test01
		{
			public Test02 doSome(){
				return null;
			}
		}


	多态:父类引用指向子类对象:Animal a = new Cat();//这种方式被称为向上转型
	
	父类引用指向子类对象,但不能引用子类特有的实例方法,
	因为编译阶段,编译器在父类中找不到子类特有的方法
	Animal a = new Cat();
	a.catchMouse();//catchMouse是cat特有方法,父类没有,编译失败,这叫做编译阶段的静态绑定失败

	//如果非要让父类引用调用子类特有实例方法,该使用向下转型
	((Cat)a).catchMouse();//向下转型 
	//向下转型时,如果把a转成Bird,虽然编译不会报错,但由于a的底层是Cat,不是Bird,所以运行时会出现报错
	//java.lang.ClassCastException: class Bird cannot be cast to class Dog//类型转换异常

	//为了避免向下转型时发生错误,可以用运算符:instanceof
	instanceof 可以在运行阶段动态判断引用指向的对象的类型
	语法:引用 instanceof 类型,返回布尔类型结果
	在使用向下转型的的时候,先用if判断真假

	软件七大原则:OCP(开闭原则)对扩展开放,对修改关闭

12.super 关键字
	super能出现在实例方法和构造方法中
	super的语法 “super.” “super()”
	super不能使用在静态方法中
	
	super.大部分情况下可以省略
	super.父类成员变量,通过super.直接访问父类成员变量和方法,但不能访问私有成员


	super()只能出现在构造方法的第一行,通过当前的构造方法去调用父类中的构造方法,目的是代码复用
	//创建子类对象之前,先初始化父类型特征

	class A
	{
		public A(int i){}//有参构造,父类中的无参构造不再提供
	}

	class B extends A
	{
		public B(){//在构造函数第一行,既没有this(),也没有super()时,系统会自动提供super(),
					//但父类没有无参构造,导致编译错误
					//错误: 无法将类 A中的构造器 A应用到给定类型
			
		}
	}
	//子类构造方法执行时,必定会调用父类的构造方法

六 IDEA
1.SRC (source) 源文件夹

2.IDEA快捷键
	file->new->module //新建module(模块)
	psvm	//快速生成main方法
	sout	//快速生成System.out.println()
	ctrl Y	//删除一行
	左侧窗口 左箭头关闭,右箭头展开,上下箭头移动
	alt+左箭头/右箭头	//切换窗口
	alt+ins //新建文件,新建构造,新建set get方法,重写
	alt+数字	//打开相应窗口
	esc		//退出窗口
	CTRL+shift+F12 //窗口变大,变小
	alt+回车		//纠正错误
	ctrl+/			//快速注释
	ctrl+shift+/	//快速注释

	字体设置:
		file->setting->font

3.final关键字
	采用final修饰的类不能被继承,
	子类不能覆盖,重写父类中被final修饰的方法

	用final修饰的局部变量只能赋值一次,不能重新赋值,相当于const修饰局部变量

	final修饰的成员变量必须在本类中初始化后,或者用构造方法初始化后才能使用,不能使用系统默认值

	final修饰的成员变量一般和static联合使用,被称为常量

	final修饰的引用不能重新指向新的对象

4.抽象类
	抽象类本身无法实例化,只能用来被继承,但抽象类中有构造方法,因为子类中有super();
	抽象类的子类也可以是抽象类
	语法:【修饰符列表】 abstract class 类名
				{
					类体;
				}

	抽象方法是没有实现的方法:
	语法:public abstract void doSome();//把他当作纯虚函数来理解

	抽象类中不一定有抽象方法,有抽象方法一定是抽象类
	非抽象子类必须具体实现抽象父类中的抽象方法!

5.接口
	接口是一种引用数据类型,编译之后也是class文件
	接口是完全抽象的。(抽象类是半抽象的)或者说接口是特殊的抽象类
	
	接口语法:
		【修饰符列表】 interface 接口名
		{
		}
	
	接口与接口可以继承,也支持多继承
		interface A extends B,C
		{
		}
	接口中只包含两部分内容:
		常量
		抽象方法//在接口中的抽象方法可以省略public abstract关键字,因为接口中的方法必定是公开的抽象方法
		//接口中的public static final 也可以省略,因为它修饰的变量是个常量,而接口中的变量必定是常量
	//接口中所有的元素都是用public来修饰的,都是公开的
	
	类和类之间叫做接口,类和接口之间叫做实现。(可以把实现看作继承)
	实现的关键词是 implements
	语法: class 类名 implements 接口名//相当于c++中的纯虚函数 virtual void doSome() = 0;
			{							//虚函数是是实现c++多态的机制,迟后联编
			}
	可以用接口的引用指向子类型的对象,但接口不能实例化
	
		接口名 in = new 子类名() 

	一个类可以实现多个接口
			class 类名 implements 接口名1,接口名2{
			}


	接口和接口之间即使没有继承关系,也可以强转!但运行时可能会出现classcastexception异常
			interface A{
			}
			interface B{
			}
			class Calculate implements A,B{//对于同时实现的A,B两个接口,可以互相转换类型
			}							//但是若只实现了其中一个,虽然接口之间还是强转可以通过编译,
										//但运行时可能会出现classcastexception异常

	继承和实现都存在的话,继承在前,实现在后
			class Animal{
			}
			interface Flyable{
			}
			class Cat extends Animal implements Flyable{//继承在前,实现在后
			}
	
	
6.接口在开发中的作用
	接口在开发中的作用类似于多态的作用,就是面向抽象编程,降低程序耦合度,提高程序扩展力
	以后面向抽象编程就是面向接口编程,有了接口就有了可插拔

	接口可以解耦合,任何一个接口都有调用者和实现者。接口可以将调用者和实现者解耦合
	调用者面向接口调用,实现者面向接口编写实现

7.package和import机制
	7.1 package是Java中的包机制,为了方便程序的管理
		不同功能的类分别放在不同的包下

	7.2 package是一个关键字,后面加包名,例如:
		package com.bjpowernode.javase.chapter17;
		注意:package语句只允许出现在Java源代码的第一行

	7.3 包名命名规范:
		一般都采用公司域名的方式(因为公司域名具有全球唯一性)
		包名命名规范:
			公司域名倒序+项目名+模块名+功能名

	7.4 对于带有package的Java程序编译与运行
		package com.bjpowernode.javase.chapter17;
		采用之前的编译和运行方式会报错(wrong name),
		因为此时的类名是com.bjpowernode.javase.chapter17.类名

		编译方式:javac -d . HelloWorld//带包编译,可以自动生成包的文件夹
			-d	带包编译
			.	代表编译之后生成的东西放到当前目录下

	7.5	若多个类在同一个package下,则这些类互相调用不需要写类的全称
		public class Test03//这个类是在d:\Java笔记\Java程序目录下
		{
			public static void main(String[] args){
				com.Test02 t = new com.Test02();//通过完整类名调用
				t.print();
			}
		}
			

			package com;//这个类是在d:\Java笔记\Java程序\com目录下
			public class Test02
			{
				public void print(){
					System.out.println("Hello World");
				}
			}
		//上述两个类不在同一package下,Test03调用Test02时需要通过完整类名com.Test02来调用



		//但是若只是单纯的把Test03.java放入和Test02.class一样的目录下,编译也无法通过,
		public class Test03//此时Test03和Test02目录一样,都在d:\Java笔记\Java程序\com目录下
		{
			public static void main(String[] args){
				Test02 t = new Test02();
				t.print();
			}
		}
		package com;//这个类是在d:\Java笔记\Java程序\com目录下
		public class Test02
		{
			public void print(){
				System.out.println("Hello World");
			}
		}
		//但此次编译无法通过,因为Test03中的Test02没有通过完整类名来调用


		//若想省略完整类名,则要么将Test03加入到com的package中去,
		package com;//这一步就是将Test03加入了com的package包中
		public class Test03
		{
			public static void main(String[] args){
				Test02 t = new Test02();//此时就可省略完整类名来调用了
				t.print();
			}
		}


		//或者使用import机制将Test.class所在的package导入到需要的类中,就可以直接调用了
		import com.Test02;//import导入
		public class Test03
		{
			public static void main(String[] args){
				Test02 t = new Test02();
				t.print();
			}
		}

		/*****/
		import com.*;//这种导入方式是将此package下的所有字节码文件全部导入

	7.6 对Scanner和String的分析
		java.util.Scanner 就是一个package包,可以用import java.util.Scanner;
		对于String,有两种用法:
			java.lang.String name = "张三";//通过package的完整类名
			String username = "李四";//java.lang不写也行,但使用String时并没有导入,为什么可以使用呢?
			//因为lang包下的文件不需要导入,都是自动导入的

8.访问控制权限
				类的内部		同一个包内		子	类		任何地方
	private		  可以				不			  不		   不
	default		  可以				可以		  不		   不
	protected     可以				可以		可以		   不
	public		  可以				可以		可以		  可以	
	//default是默认的,只要不写就默认是default
	
	//访问控制权限可以修饰属性,方法,静态方法,类

七 Java源码分析
1.Object类——jdk类库的根类
如何查看Java类中的方法?
第一种,去源码中查看
第二种,查阅Java的类库的帮助文档
API(应用程序编程接口)
整个JDK的类库(sun公司提前写好的)就是一个javase的API,每个API都会配置一套API帮助文档

	目前需要学习的方法:
		protected Object clone()	//负责对象克隆的。
		int hashCode()				//获取对象的哈希值
		boolean equals(Object obj)	//判断两个对象是否相等
		String toString()			//将对象转换成字符串形式
		protected void finalize()	//垃圾回收器负责调用的方法

2.toString()方法
	public String toString(){//源码
		return this.getClass().getName() + "@" + Integer.toHexString(hashCode());
	}//返回的是一串字符串:类名@对象的内存地址所转换的16进制形式

	//sun公司建议所有子类都重写toString()方法

3.equals()方法
	public boolean equals(Object obj){//源码
		return (this == obj);
	}//判断两个对象是否相等
	// == 不能比较引用的对象内容是否相等,因为引用存储的是内存地址
	//比较字符串不能使用 == ,只能使用equals方法


4.String是一个类,不是基本数据类型,有自己的构造方法
	String s1 = "张三";
	String s2 = "张三";
	String s3 = new String("张三");
	String s4 = new String("张三");

	System.out.println(s1 == s2);//true
	System.out.println(s3 == s4);//false
	System.out.println(s1.equals(s2));//true
	System.out.println(s3.equals(s4));//true

	//因为new是在堆内存开辟空间,String类型数据又是存储在方法区的常量池的,
	//所以,栈区引用指向的堆内存保存了指向方法区的String类型的数据,
	//用new方法开辟的String数据,栈区引用指向不同的堆内存,但不同的堆内存指向相同的方法区数据,
	//所以后面两个定义比较会是false,而前面两个定义则是栈区引用直接指向方法区数据,
	//栈区保存的方法区内存地址一致,所以结果是true;

	//对于比较string类型的数据,用equals方法最好,不会出错

5. finalize()方法
	这个类是protected修饰的,finalize()方法只有一个方法体,里面没有代码
		protected void finalize() throws Throwable{}
		//这个方法不需要程序员手动调用,JVM的垃圾回收器负责调用这个方法
		//当一个Java对象即将被gc回收时,gc负责调用finalize()方法
		//如果希望在对象销毁时执行一段代码的话,这段代码要写到finalize()方法中
		//可以理解为C++中的析构函数

		//项目开发中的业务需求:所有对象在JVM中被释放时,记录一下释放时间,负责记录的代码可以写到finalize里
		
		//Java中垃圾回收器不轻易启动,垃圾太少或者时间不到,有可能启动也有可能不启动
		//有一段可以建议启动gc,但只是建议,不一定会启动
		System.gc();

6.hashCode();
	public native int hashCode();//返回的是哈希码:
		实际上是Java对象的内存地址,经过哈希算法,得出的一个值。
		所以哈市Code()方法执行的结果可以等同看作一个Java对象的内存地址

7.内部类(类里面套一个类)
	内部类分为四个类:
		实例内部类:类似于实例变量
		局部内部类:类似于局部变量
		静态内部类:类似于静态变量
		匿名内部类:是一种特殊的内部类,该类没有名字(匿名内部类属于局部内部类的一种)
		
		class Test01
		{
			static class Inner1//静态内部类
			{
			}

			class Inner2//实例内部类
			{
			}
			public void doSome(){
				class Inner3//局部内部类
				{
				}
			}
		}
		//编译的结果:
			//Test01.class
			//Test01$Inner1.class
			//Test01$Inner2.class
			//Test01$Inner3.class

8.匿名内部类
	interface Compute
	{
		int sum(int x,int y);
	}

	class MyMath
	{
		public void mySum(Compute c,int x,int y){
			c.sum(x,y);
		}
	}
	public class Test
	{
		public static void main(String[] args){
			MyMath mm = new MyMath(new Compute(){具体实现},20,30);//这,就是匿名内部类的用法
		}
	}

八 数组
1. Java中的数组定义:
基本数据类型:
int[] array = {1,2,3,4,5}; //静态初始化
int[] array1 = new int[10];//动态初始化

		引用数据类型:
		Person[] array = new Person[10];//定义一个Person类型的数组,数组内部应该保存的是Person的引用
		for(int i=0;i<10;i++)
		p[i] = new Person();//数组内部保存的是引用,引用指向对象。所以需要为每个数组元素new一个对象,
							//否则会造成空指针异常
2.* Array
	*   1.java语言中的数组是一种引用数据类型,不属于基本数据类型。数组的父类是Object
	*   2.数组实际上是个容器,可以容纳多个元素
	*   3.数组因为是引用数据类型,所以是存储在对内存当中的
	*   4.引用类型的数组,其在堆内存存放的是对象的引用(指针),指向对象(也在堆内存)。
	*   5.数组一旦创建,在Java中规定,长度不可变(数组长度不可变)
	*   6.所有的数组对象都有length属性(Java自带)
	*   7.数组的内存地址是连续的,每个元素占用内存空间大小相同

3.方法的参数是数组
	printArray(new int[]{1,2,3})//如果想用静态数组传参,必须这样写
	printArray(new int[5])//动态数组传参

4.main(String[] args)中的数组分析
	JVM调用main方法,会自动传一个String数组过来
	args.length 的输出结果是 0,长度是0,不是NULL,表示数组对象创建了(不是null),
	但是数组内部没有存任何东西(长度为0);
	
	//这个数组什么时候会有值呢?
	//这个数组是留给用户的,用户可以在控制台上输入参数,这个参数自动会被转换为String[] args
	//例如这样运行数组:java ArrayTest abc def xyz
	//那么这个时候JVM会自动将abc def xyz自动放到String[] args数组中

	idea中设置“java ArrayTest abc def,xyz”:
		run->edit configurations->program arguments//设置运行时参数

	"admin".equals(userName)//这种调用方法永远也不会出现空指针异常

5.数组扩容
	先新建一个大容量数组,再将小容量数组内的数据拷贝到大数组中
	数组扩容效率低。

	数组拷贝函数
	System.arrayCopy(源数组,源数组拷贝的起始位置,目标数组,插入目标数组的位置,拷贝的长度)
	//位置是下标,从0开始的

6.数组工具类
	java.util.Arrays;//工具包,里面有很多方法
		sort(int[] a)//排序方法
		binarySearch(arr,key)//二分法查找关键字 

九 常用类(主要方法都在文档)
1. String //Java.lang包下
Java中规定,双引号括起来的字符串是不可变的,都是直接存储在方法区的字符串常量池中
String s1 = “abcdefg”//存储在方法区的字符串常量池中

	String s2 = new String(arr)//这个arr是个byte类型数组,此时输出s2,会转为ASCII码
	compareTo()//比较两个字符串首字母大小,如果相等就比较下一个字母
	boolean contains(CharSequence s)//判断前面的字符串中是否包含后面的字符串
	boolean endsWith(String suffix)//判断当前字符串是否以某个字符串结尾
	boolean startsWith(String prefix)//判断当前字符串是否以某个字符串开始
	boolean equalsIgnoreCase(String anotherString)//判断两个字符串是否相等,忽略大小写
	byte[] getBytes()//将字符串对象转换为字节数组
	int indexOf(String str)//判断某个子字符串中第一次出现处的下标
	boolean isEmpty()//判断某个字符串是否为空
	String subString(int beginIndex)//截取字符串
	String subString(int beginIndex,int endIndex)//截取一段字符,左闭右开,endIndex取不到
	char[] toCharArray()//转换成char数组
	String toLowerCase()//转换成小写
	String toUpperCase()//转换成大写
	String trim()//去除字符串前后空白
	String.valueOf//String 中只有一个static方法,将非字符串转换为字符串,底层调用了toString()方法

2.字符串拼接
	由于java字符串不可变,用加号来实现字符串拼接,都会产生新的字符串,这样会占用大量的内存
	如果需要频繁的拼接字符串,可以用java.lang.StringBuffer或者java.lang.StringBuilder
	StringBuffer sb = new StringBuffer();//StringBuffer是开辟新的内存空间用于存储
	//StringBuffer底层实际是一个初始容量为16的byte[]数组,往StringBuffer中放字符串,实际是放到byte数组当中
	//若是byte[]数组容量满了,他会自动扩容
	sb.append("a");//使用append底层追加字符,不会生成新的对象
	sb.append("a");//实际是将字符放入数组
    sb.append("b");
	System.out.println(sb.toString());

	为了提高StringBuffer的性能,在创建StringBuffer的时候尽可能给定一个初始化容量,
	最好减少底层数组的扩容次数,预估计一下,给一个大一点的初始化容量

	StringBuilder sb = new StringBuilder();//初始化一个容量16的
	sb.append("");//用法与StringBuffer一样
	StringBuilder 与 StringBuffer的区别:
	StringBuffer 中的方法,都有:synchronized 关键词修饰。表示Stringbuffer在多线程环境下运行是安全的
	StringBuilder 中的方法没有synchronized 关键词修饰,表示StringBuilder在多线程环境下运行时不安全的

3.基础类型对应的8个包装类 
	Java为8中基本数据类型对应准备了8种包装类型,8种包装类属于应用数据类型
		byte	java.lang.Byte		(父类number)
		short	java.lang.Short		(父类number)
		int		java.lang.Integer	(父类number)
		long	java.lang.Long		(父类number)
		float	java.lang.Float		(父类number)
		double	java.lang.Double	(父类number)
		boolean	java.lang.Boolean	(父类Object)
		char	java.lang.Character (父类Object)

4. 通过 Integer.MAX_VALUE 来获得该类型的最大值上限
   通过 Integer.MIN_VALUE 来获得该类型的最小值下限

5.	自动装箱:Integer x = 100;//可以直接参与计算,在计算前会进行自动拆箱
	自动拆箱:int y = x;
	//只有加减乘除的时候才会自动拆箱,其他时候不会自动拆箱

	对于Integer x = 128;
		Integer y = 128;
		System.out.println(x == y)//false;

		Integer x = 127;
		Integer y = 127;
		System.out.println(x == y)//true;

		//因为-128~127比较常用,所以直接被放在了常量池
		//所以所有指向这个范围的数据类型,只要指向的数字一样,他们就是存储着相同的地址
	Integer a = new Integer("123");//可以
	Integer a = new Integer("中文");//数字格式化异常

	重要方法:
		Integer.parseInt("123");//将数字字符串转换为Int类型
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值