final关键字代表最终、不可改变的。
常见四种用法:
当final修饰一个类的时候,其格式:
public final class 类名称(){ //.............. }
含义:当前这个类不能有任何的子类。(太监类)
当final修饰一个方法的时候,其格式:
修饰符 final 返回值类型 方法名称(参数列表){ //方法体 }
当final关键字用来修饰一个方法的时候,这个方法就是最终方法,也就是不能被覆盖重写。
当final修饰局部变量的时候
对于基本类型来说,不可变说的是变量当中的数据不可改变
对于引用类型来说,不可变说的是变量当中的地址值不可改变
当final修饰成员变量的时候
对于成员变量来说,如果使用final关键字修饰,那么这个变量也照样是不可变。
1、由于成员变量具有默认值,所以用了final之后必须手动赋值,不会再给默认值了。
2、对于final的成员变量,要么使用直接赋值,要么通过构造方法赋值。二者选其一。
3、必须保证类当中所有重载的构造方法,都最终会对final的成员变量进行赋值。
分类:
1、成员内部类
2、局部内部类(包含匿名内部类)
修饰符 class 外部类名称{ 修饰符 class 内部类名称{ //............. } //............. }
注意:内用外,随意访问; 外用内,需要内部类对象。
public class Outer { int num = 10; //外部类的成员变量 public class Inter{ int num = 20; //内部类的成员变量 public void methodInner(){ int num = 30; //内部类方法的局部变量 System.out.println(num);//局部变量,就近原则 System.out.println(this.num);//内部类的成员变量 System.out.println(Outer.this.num);//外部类的成员变量 } } }
修饰符 class 外部类名称{ 修饰符 返回值类型 外部类方法名(参数列表){ class 内部类名称{ //............. } } }
小节一下类的权限修饰符:
定义一个类的时候,权限修饰符规则:
局部内部类的使用方法为:在外部类new内部类,调用方法
如果接口的实现类(或者是父类的子类)只需要使用唯一的一次。
那么这种情况下就可以省略掉该类的定义,而改为使用【匿名内部类】。
格式:
接口名称 对象名 = new 接口名称(){ //覆盖重写所有抽象方法 };
注意事项:
集合和数组既然都是容器,它们有啥区别呢?
1、学习顶层:学习顶层接口/抽象类中共性的方法,所有的子类都可以使用
⒉、使用底层:顶层不是接口就是抽象类,无法创建对象使用,需要使用底层的子类创建对象使用
java.util.collection接口
public boolean add(E e): 把给定的对象添加到当前集合中。
public void clear(): 清空集合中所有的元素。
public boolean remove(E e): 把给定的对象在当前集合中删除。
public boolean contains(E e): 判断当前集合中是否包含给定的对象。
public boolean isEmpty(): 判断当前集合是否为空。
public int size(): 返回集合中元素的个数。
public object[] toArray(): 把集合中的元素,存储到数组中。
public class DemoCollection { public static void main(String[] args) { Collection<String> coll = new ArrayList<>(); System.out.println(coll);//[] boolean a = coll.add("张三"); System.out.println("a:"+a);//a:true coll.add("李四"); coll.add("王五"); coll.add("赵六"); coll.add("田七"); System.out.println(coll);//[张三, 李四, 王五, 赵六, 田七] boolean b = coll.remove("王五");//删除指定元素 System.out.println("b:"+b);//b:true boolean c = coll.remove("田七"); System.out.println("c:"+c);//c:true System.out.println(coll);//[张三, 李四, 赵六] boolean d = coll.contains("张三"); System.out.println("d:"+d);//d:true boolean e = coll.isEmpty();//判断是否为空 System.out.println("e:"+e);//e:false Object[] obj = coll.toArray();//把集合中元素存到数组中 for (int i = 0; i < obj.length; i++) { System.out.println(obj[i]); } int size = coll.size();//返回个数 System.out.println("元素个数为:"+size);//元素个数为:3 coll.clear(); System.out.println(coll);//[] 清空元素,但是集合还在 } }
在程序开发中,经常需要遍历集合中的所有元素。针对这种需求,JDK专门提供了一个接口 java.util.Iterator 。Iterator接口也是Java集合中的一员,但它与collection、Map 接口有所不同,collection接口与Map接口主要用于存储元素,而Iterator主要用于迭代访问(即遍历) collection 中的元素,因此Iterator对象也被称为迭代器。
有两个常用的方法
Iterator迭代器,是一个接口,我们无法直接使用,需要使用Iterator接口的实现类对象,获取实现类的方式比较特殊
collection接口中有一个方法,叫iterator(),这个方法返回的就是迭代器的实现类对象
Iterator
迭代器的使用步骤(重点):
1、使用集合中的方法iterator()获取迭代器的实现类对象,使用Iterator接口接收(多态)
2、使用Iterator接口中的方法hasNext判断还有没有下一个元素
3、使用Iterator接口中的方法next取出集合中的下一个元素
public class DemoIterator { public static void main(String[] args) { Collection<String> coll = new ArrayList<>(); coll.add("吕布"); coll.add("赵云"); coll.add("典韦"); coll.add("张飞"); //Iterator<E>接口也是有泛型的,迭代器的泛型跟着集合走,集合是什么泛型,迭代器就是什么泛型 Iterator<String> it = coll.iterator(); while (it.hasNext()){ String a = it.next(); System.out.println(a); } } }
增强for循环(也称for each循环)是JDK1.5以后出来的一个高级for循环,专门用来遍历数组和集合的。它的内部原理其实是个lterator迭代器,所以在遍历的过程中,不能对集合中的元素进行增删操作。
格式:
for(元素的数据类型 变量 : Collection集合or数组){ //操作代码 }
public class DemoForEach { public static void main(String[] args) { demo1(); demo2(); } public static void demo1(){ int[] array = {1,2,3,4,5}; for (int i : array){ System.out.println(i); } } public static void demo2(){ ArrayList<String> list = new ArrayList<>(); list.add("aaa"); list.add("bbb"); list.add("ccc"); for (String s : list){ System.out.println(s); } } }
泛型是一种未知的数据类型,当我们不知道使用什么数据类型的时候可以使用泛型
ArrayList集合在定义的时候不知道集合中都会存储什么类型的数据,所以类型使用泛型
public class ArrayList<E>{ public boolean add(E e){} public E get(int index){} }
创建集合对象的时候就会确定泛型的数据类型
ArrayList<String> list = new ArrayList<>();
public class ArrayList<String>{ public boolean add(String e){} public String get(int index){} }
创建集合对象,使用泛型好处:
避免了类型转换的麻烦,存储的是什么类型,取出的就是什么类型
把运行期异常(代码运行之后会抛出的异常),提升到了编译期(写代码的时候会报错)
弊端:
泛型是什么类型,只能存储什么类型的数据
public class Class<E> { private E name; public E getName() { return name; } public void setName(E name) { this.name = name; } }
public class DemoClass { public static void main(String[] args) { Class<String> Sc = new Class<>(); Sc.setName("张三"); String name = Sc.getName(); System.out.println(name); Class<Integer> Sc1 = new Class<>(); Sc1.setName(1); Integer name1 = Sc1.getName(); System.out.println(name1); } }
public class Demo1 { //定义一个范型的方法 public <E> void method(E e){ System.out.println(e); } //定义一个静态的范型方法 public static <M> void method1(M m){ System.out.println(m); } }
public class DemoGenericMethod { public static void main(String[] args) { Demo1 demo1 = new Demo1(); //传递的是什么类型,范型就是什么类型 demo1.method("张飞"); demo1.method(1); demo1.method(3.4); demo1.method(true); Demo1.method1("静态方法不推荐创建对象使用"); } }