① Java内存结构
1.1 内存结构
简单数据类型 :只涉及到栈内存
引用数据类型 :栈内存+堆内存
栈,先进后出(FILO—First-In/Last-Out)
堆,队列优先,先进先出(FIFO—first in first out)
栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。
堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。
② 对象
Java中:一切皆对象;面向对象其实是计算机编程技术发展到一定阶段后的产物,在java中,对象其实就是类的一个具体实例。从概念上讲分为3种:
OOA: 面向对象分析 Object Oriented Analysis
OOD: 面向对象设计 Object Oriented Design
OOP: 面向对象程序 Object Oriented Programming
面向对象有三大特性:封装性、继承性、多态性
2.1 对象的定义格式
类名称 对象名称 = new 类名称 ()
Person per = new Person ()
访问类中属性 :对象.属性;
访问类中的方法 : 对象.方法
不管任何情况下,只要调用了关键字new,则表示开辟了新的堆内存空间。
成员变量可以全局使用(有默认初始值);
局部变量只能在当前的方法中使用(无默认初始值,必须赋值)
默认初始值:
int = 0
boolean = false
char = ☐
String = null
2.2 封装性
封装性 :所有内容对外部不可见 加private修饰 (可通过get和set间接获取和设置)
修饰符 + 返回值 + 方法名(参数列表){方法体}
public String getName(){ return name; } public void setName(String name){ this.name = name; }
void 无返回值
2.3 继承(extends)
2.3.1 特点
子类 extends 父类
子类继承父类之后,就拥有了父类权限中可以拥有的一切数据
作用 :提高代码的复用率
2.3.2 注意事项
1、private 无法继承 但可以通过间接方法获取属性
2、子类的功能要比父类更加丰富
3、java 支持多层继承,但是有单根继承局限性(只能同时继承一个父类)
4、子类方法的访问权控制符,只能和父类一样;只能更开放,不能更封闭;
5、子类中的同名属性会覆盖父类
6、在进行子类对象的实例化之前会首先默认调用父类的无参构造器,为父类中的属性进行初始化操作,之后再调用子类自己的构造器完成子类的初 始化操作
7、在子类中可以通过super关键字明确指出要调用父类中的哪个构造器
8、如果没有写任何的super语句,则在子类构造器中默认隐含了一个“super()”
9、final修饰的类不能被子类所继承 final修饰的方法不能被子类所覆写
2.4 多态
1、方法的重载(不是严格意义上的多态) 2、对象多态性
2.4.1 特点
声明一个父类的引用,赋值一个子类对象(声明父类new子类),调用方法时,该方法必须在父类中有声明(先用子类方法,没有再调用父类方法)
自动类型转换 (向上转型)
Person per = new Student();
强转(向下转型)
Person per = new Stdent();
Student stu = (Student) per;
(可以用per instanceof Student判断是否能强转)
向下转型错误写法 :Student stu1 = (Student)new Person();
一个对象想要进行向下转型之前,要首先进行向上转型操作,建立关系;
声明一个父类,new子类,调用方法时,该方法必须在父类中有声明;真正方法调用执行时,如果子类有方法,执行子类的方法,如果子类没有,执行父类的方法;如果每个子类都覆写父类的方法,则父类方法不会被执行。但父类方法不能被删除,删除就意味着父类没有这个行为。
此时,可以把该方法变为抽象方法;因为有抽象方法,该类必须被定义为抽象类。
③ 方法重载
3.1 定义
同名方法,根据参数列表的不同,可以出现多次
一个参数列表只允许有一个可变参数,但可以有多个固定的放前面,可变的必须放最后。
public void go(int num,double a,String...strs){
}
String...strs 是可变参数,可以传入任意个数的string字符串,通过遍历数组可以拿到数据。
④ 构造器
4.1 特点
1、特殊方法 new对象时自动调用
2、没有返回值这一项
3、方法名必须和当前类名一致
4、构造器也可以重载
5、构造器之间可以通过this 关键字相互调用
6、this 在调用构造器时必须放在第一行
public class Dog { String name; int age; public Dog(){ this(123); System.out.println("我是Dog的0参数构造器。我被调用到啦。。"); } public Dog(int num){ this("xxx"); System.out.println("我是Dog的1...int参数构造器。我被调用到啦。。"); } public Dog(String str){ this(123,"vvv"); System.out.println("我是Dog的1...String参数构造器。我被调用到啦。。"); } public Dog(int num,String str){ System.out.println("我是Dog的2...参数构造器。我被调用到啦。。"); age=num; name=str; } public void go(){ System.out.println("gogogogo..."); } } public class Test { public static void main(String[] args) { Dog dog=new Dog(22,"旺财"); System.out.println(dog.age); System.out.println(dog.name); // Dog dog1=new Dog(123); // Dog dog2=new Dog("xxx"); // Dog dog3=new Dog(123,"aaa"); } }
⑤ String 类
5.1 特点
赋值:
1、new 对象赋值 String str1 = new String(“aaa”);
2、直接赋值 String str2 = “xxx”;
(1). 一个字符串就是String 的匿名对象
(2). String 堆内存的值是不可改变的
String str
栈内存开辟一块空间,存储str引用
String str=null
栈内存开辟一块空间,存储str引用
堆内存中开辟一块空间,str指向那块空的内存的地址
String str=“”
栈内存开辟一块空间,存储str引用
堆内存中开辟一块空间,里面存放一个空窜,str指向空窜的地址
String str=new String(“aaa”)
栈内存开辟一块空间,储存str引用,
堆内存中开辟一块新空间,里面存放一个aaa,str指向aaa的地址
用new String() 创建的字符串不是常量,不能在编译期就确定,所以new String() 创建的字符串不放入常量池中,它们有自己的地址空间
String.intern():
存在于.class文件中的常量池,在运行期被JVM装载,并且可以扩充。String的 intern()方法就是扩充常量池的 一个方法;当一个String实例str调用intern()方法时,Java 查找常量池中 是否有相同Unicode的字符串常量,如果有,则返回其的引用,如果没有,则在常量池中增加一个Unicode等于str的字符串并返回它的引用
常量池在java用于保存在编译期已确定的,已编译的class文件中的一份数据。它包括了关于类,方法,接口等中的常量,也包括字符串常量,如String s = "java"这种申明方式;当然也可扩充,执行器产生的常量也会放入常量池,故认为常量池是JVM中的一块特殊的内存空间
= = 比较地址
equals()比较要看它是否有覆写object的equals()方法。如果没有,他比较的也是地址。如果有,那么很有可能他比较的是值,但也不尽然。比如Integer a=1;Double b=1; a.equals(b)是false
string类由于覆写了object的equals()方法,equals()比较的是“值”
5.2 常用方法
"goodlook"
1、转换为字节数组:getBytes();
2、转换为字符数组:toCharArray();
3、以某个字符序列开头/结尾: startsWith(go)/endsWith(ok);
4、截取: substring(3) 从第3截取到最后 substring(3,4)截取第3个 截取开头 不截取尾巴
5、拆分: split(“oo”)/(“o”,2);
6、查找: indexOf();
7、获取长度: length(); //length()方法
8、去首尾空格:trim();
9、字符数组--->字符串
char[] c = {‘A’ ,‘+’,‘-’ ,‘$’};
System.out.println(new String(c));
10、是否包涵:contains(“ood”)
11、转换为 int 型
“123”----》123
String s = 123;
int num = Integer.parseInt(s);
⑥ this关键字
6.1 功能
1、调用类中的属性
2、调用类中的方法或构造方法
3、表示当前对象
this.属性 : 调用当前类的属性
this.方法 : 调用当前类的方法
⑦ Scanner 录入
import java.util.Scanner import java.util.* Scanner sc =new Scanner(System.in); String str = sc.nextLine(); int a =Integer.pareseInt(sc.nextLine()); int num = sc.nextInt(); if(Scanner.hasNextInt){ num = Scanner.nextInt(); } Scanenr.next(); Scanenr.nextInt(); //遇到空格、Tab、回车时中断,不会读取空格、Tab、回车; Scanner.nextLine(); //遇到回车时中断,会读取空格、Tab、回车;
不同包下的调用(在类前加import 包.class名 或 包.*)
⑧ static 静态
8.1 特点
-----为所有对象所共同使用-----全局数据区------类加载时诞生
调用 : 调用static修饰的属性和方法根本无须对象,可以通过类名.属性/类名.方法名调用
限制 : 1、静态只能调用静态,非静态则无此限制
2、static只能修饰成员
3、静态方法中不能使用this,super;(this和super是属于对象范畴的东西,而静态方法是属于类范畴的东西;this和super代表的是调用对象的引用,而静态方法是属于类的,不属于对象,静态方法成功加载后,对象还不一定存在)
⑨ abstract 抽象类
9.1 特点
由来 :当一个父类中的方法都被其子类所覆写时,这个方法的方法体存在就没有意义,可以去除其方法体,定义为抽象方法,让子类自己去覆写,由于类中有了抽象方法,该类就必须定义为抽象类(abstract)
抽象方法的作用就是,类有这个行为,但是,没有行为的实现;需要在子类中实现
1、抽象类本身不能直接进行实例化操作;即不能使用关键字new完成
一个抽象类必须被子类所继承,继承的子类(如果不是抽象类)则必须覆写抽象类中的所有抽象方法
2、抽象类不能用final声明;因为final是终结器,其修饰的类不能有子类;而抽象类是必须有子类的
3、抽象类能有构造方法;与普通类的继承一样,默认先调用父类的无参构造器,之后再调用子类自己的构造器
⑩ super 关键字
10.1 特点
1、super.属性名 :调用父类属性
2、调用父类方法
3、调用父类的构造器(默认调用父类的无参构造器)
注意 :(1)必须写在第一行
(2)this 、super不能同时出现
⑪ final 关键字
11.1 特点
final表示最终态
1、使用final声明的变量即成为常量;修饰成员变量时必须给值;修饰局部变量时可以不给初始值
2、修饰方法-----方法不可被子类覆写
3、修饰类------类不可被继承
4、使用public static final 修饰的常量为全局常量
⑫ interface 接口
interface 接口名称 {
全局常量 ----所有属性都是 public static final
抽象方法 ----所有方法都是 public abstract
}
全局常量命名时全部大写,可加下划线(PERSON_NAME)
接口不是类,接口就是接口,不是从object中继承,接口可以从多个接口继承
类和类的关系是继承(单根) 接口和接口也是继承 类和接口的关系是实现
接口不能 new
public interface A { String name = “A类” public static final String PERSON_NAME = “人类名字”; public abstract void go(); public abstract int getNum(); } class Text implements A { public void go(){ } public int getNum(){ return 1; } //eclipse1.8新增接口内容 :静态方法(static)、默认方法(default) public interface A { public static void go1(){ System.out.println("xxxxxxxxxx"); } public default void go2(){ System.out.println("aaaaaaaaaa"); } } class B implements A{ } public class Text { public static void main(String[]args) { B b = new B(); b.go2(); A.go1(); } }
⑬ 对象数组
Person per1 = new Person (“张三1”,12);
Person per2 = new Person (“张三2”,13);
Person per3 = new Person (“张三3”,14);
Person [] pers = { per1,per2, per3};
对象数组在使用某个位置元素之前,必须把该位置的元素给实例化了;
① 实例化数组
② 实例化某个位置的对象
⑭ 代码块
类 {
中间都是代码块
}
方法中的代码叫普通代码块
{
System.out.println(“-------”);//游离代码块
}
静态代码块只在类运行时加载一次
static{
int a=0;
string b=“b”
}
⑮ 静态绑定和动态绑定
绑定指的是一个方法的调用与方法所在的类(方法主体)关联起来。对java来说,绑定分为静态绑定和动态绑定;或者叫做前期绑定和后期绑定
15.1 作用
作用 :声明父类new子类,决定所使用的元素是父类的还是子类的
15.2 特点
静态绑定 :在程序执行前属性或方法已经被绑定,此时由编译器或其它连接程序实现
所有的属性,构造器,还有用private,static,final 修饰的方法都属于静态绑定,都是使用父类的元素。
动态绑定 :后期绑定:在运行时根据具体对象的类型进行绑定。
普通方法为动态绑定,调用子类自己的
⑯ 内部类
1、(类中类)方便访问外部类的私有成员,往往有组成关系
2、使用static声明的内部类就成为外部类
3、定义在方法中的局部内部类如果想要访问方法中的参数,则参数前要加“final”关键字
普通内部类
静态内部类
局部内部类(存在于内部类的方法中,只能调用局部常量)
匿名内部类
内部类创建写法:
Outter.Inner inner = new Outter().new Inner();
外部类.内部类 对象
静态内部类创建写法:
Outter.staticInner inner = new Outter.staticInner();
匿名内部类 :
public interfaceUSB {
public void start();
public void work();
public void end();
}
public class Computer {
public void plugInUsb(USB usb){//形参传入接口或抽象类
usb.start();
usb.work();
usb.end();
}
}
public class Text {
public static void main(String[] args) {
Computer computer = new Computer();
//创建匿名内部类 USB为当前匿名内部类的匿名对象或接口的名字
computer.plugInUsb(new USB(){
@Override
public void start() {
System.out.println("开始");
} // {}中为匿名内部类(即抽象类的子类或接口的实现类)
()里为匿名内部类的匿名对像
@Override
public void work() {
System.out.println("工作");
}
@Override
public void end() {
System.out.println("结束");
}
});
}
}
⑰ Object类
Java中所有类的父类.
1、得到对象信息:public String toString()
2、进行对象比较:public boolean equls(Object obj)
3、得到对象的运行时类型:getClass()
String 类中由于子类覆写了父类,equals可以比较数值;直接从Object中继承的,equals默认比较地址(相当于==比较)
变量是null,并且调用了方法属性就会空指针异常;
⑱ Java泛型的使用
1.给类加
2.给接口加
3.给方法加 普通方法 静态方法(静态方法不能使用类的泛型) 参数/返回值
package a; /* * 1.给类加 * 2.给接口加 * 3.给方法加 普通方法 静态方法 参数/返回值 */ public interface A { public void go(T t); }
package a; public class C { public static
void go(Q t) { go1(t); } public staticvoid go1(Q t){ System.out.println("go1..."); } }package a; public class D { public T go(){ return null; } public static void main(String[] args) { D d=new D(); d.go(); int a=d.go(); String str=d.go(); } }
package a; import java.util.ArrayList; import java.util.List; public class E { public static void main(String[] args) { E e=new E(); } }
package a; public class Test { public static void main(String[] args) { A a=new B(); a.go("xxx"); } } class B implements A { @Override public void go(T t) { } }