总结java的泛型和内部类
Posted 满眼*星辰
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了总结java的泛型和内部类相关的知识,希望对你有一定的参考价值。
泛型
泛型是java1.5中增加的一个新特性,通过泛型可以写与类型无关的代码,即编写的代码可以被很多不同类型的对象所重用,经常用在一些通用的代码实现中,比如:java集合框架中的类几乎都是用泛型实现的。
泛型的本质是:类型参数化。类似函数传参一样,传递不同的实参,函数运行完将会产生不同的结果。
泛型12点总结
- class MyStack< T> 此时< T>代表是一个占位符,表示当前类是一个泛型类
- this.elem = new T[10]; 不能实例化泛型类型的数组对象
- Mystack< Integer> myStack = new MyStack<>();
MyStack< Integer> 这里指定当前类可以存放的数据类型
new MyStack<>() 与前面匹配 - 泛型的意义:
a:可以自动进行类型的检查
b:可以自动进行类型的转换 - MyStack< int> myStack = new MyStack<>();
简单类型 不能作为泛型类型的参数 包装类型->引用类型 - 泛型到底是怎么编译的? 擦除机制
擦除为Object的意义 就是可以放任意类型的数据
运行java程序的时候,是没有泛型的概念的 - MyStack< Integer> stack : 泛型类型的参数,不参与类型的组成
- 泛型的上界:
class Algorithm<T extends Comparable< T> > {}
T:T类型一定要实现Comparable接口
class Algorithm< E extends Animal> {}
E:可以是Animal的子类,或者是Animal自己类本身 - 泛型没有下界
- 泛型方法:
public static< T> T findMaxVal(T[] array) {}
public static<T extends Comparable< T>> T findMaxVal(T[] array) {} - 通配符:通配符实际上也是一种泛型。一般在源码中居多一点
泛型一般用于读取和写入,而通配符一般用于读取
public static< T> void print(ArrayList< T> list) {}
public static void print(ArrayList<?> list) {}
通配符上界:<? extends E> 表示传入的参数 ? 是上界 E 的子类或者 E 自己本身
通配符下界:<? super E> 表示传入的参数 ? 是下界 E 的父类或者 E自己本身 - ArrayList< Integer> list ArrayList< Number> list
他们不会构成父子类关系,因为类型擦除机制 以及 不参与类型的组成
class MyStack<T> {
public T[] elem;
public int top;
public MyStack() {
this.elem = (T[])new Object[10];
//this.elem = new T[10];
}
public void push(T val) {
this.elem[top] = val;
top++;
}
public T getTop() {
return this.elem[top-1];
}
}
/**
* 写一个泛型类,找到数组当中的最大值
*/
class Algorithm<T extends Comparable<T> > {
public T findMaxVal(T[] array) {
T max = array[0];
for (int i = 1; i < array.length; i++) {
if(array[i].compareTo(max) >= 0) {
max = array[i];
}
}
return max;
}
}
class Person {
}
/**
* 泛型方法
*/
class Algorithm2 {
public static<T extends Comparable<T>> T findMaxVal(T[] array) {
T max = array[0];
for (int i = 1; i < array.length; i++) {
if(array[i].compareTo(max) >= 0) {
max = array[i];
}
}
return max;
}
}
/**
*写一个方法 打印一个list当中的所有的数据
*/
class Test {
public static<T> void print2(ArrayList<T> list) {
for (T x:list) {
System.out.println(x);
}
}
public static void print(ArrayList<?> list) {
for (Object x:list) {
System.out.println(x);
}
}
}
public class TestDemo {
public static void main(String[] args) {
//Integer extends Number
ArrayList<Integer> list = new ArrayList<>();
ArrayList<Number> list2 = new ArrayList<>();
list2.addAll(list);
}
public static void main5(String[] args) {
ArrayList<Integer> list1 = new ArrayList<>();
list1.add(1);
list1.add(2);
list1.add(3);
Test.print(list1);
ArrayList<Double> list2 = new ArrayList<>();
list2.add(1.0);
list2.add(2.0);
list2.add(3.0);
Test.print(list2);
}
public static void main4(String[] args) {
Integer[] array = {1,2,3,4,5,6,7};
System.out.println(Algorithm2.<Integer>findMaxVal(array));
System.out.println(Algorithm2.findMaxVal(array));
}
public static void main3(String[] args) {
Algorithm<Integer> algorithm = new Algorithm<>();
Integer[] array = {1,2,3,4,5,6,7};
System.out.println(algorithm.findMaxVal(array));
//Algorithm<Person> algorithm2 = new Algorithm<>();
}
public static void main2(String[] args) {
MyStack<Integer> myStack = new MyStack<>();
System.out.println(myStack);
}
public static void main1(String[] args) {
/* Stack<Integer> stack1 = new Stack<>();
Stack<String> stack2 = new Stack<>();
Stack<Double> stack3 = new Stack<>();*/
MyStack<Integer> myStack = new MyStack<>();
myStack.push(1);
myStack.push(19);
myStack.push(80);
int a = myStack.getTop();
System.out.println(a);
MyStack<String> myStack2 = new MyStack<>();
myStack2.push("hello");
//假设不指定泛型的类型参数
@SuppressWarnings("unchecked")
MyStack<String> myStack3 = new MyStack();
myStack3.push("fsafsasa");
}
}
内部类
实例内部类
实例内部类: 定义在类的内部的一个类。
-
如何实例化内部类对象?
OuterClass.InnerClass innerClass2 = out.new InnerClass();
外部类名.内部类名 变量 = 外部类对象的引用.new 内部类(); -
只要是内部类,那么生成的字节码文件格式:外部类$内部类.class
-
在实例内部类当中,不能定义静态的成员变量!!
如果非要定义,那么一定要是在编译时期确定的值 public static final -
this实际上是一个静态的成员
System.out.println(OuterClass.this.data1); -
实例内部类实际上拥有2个this。一个是实例内部类自己的,一个是外部类的
所以这里有个面试题:同学,实例内部类,是否有额外的内存开销? 有
public class OuterClass {
public int data1 = 1;
public static int data2 = 2;
class InnerClass {
public int data3 = 3;
public int data1 = 11;
public static final int data4 = 4;
public InnerClass() {
}
public void test() {
System.out.println("InnerClass::test()");
System.out.println(data3);
System.out.println(data4);
System.out.println(this.data1);
System.out.println(OuterClass.this.data1);
}
}
}
public class Test1 {
//实例内部类
public static void main(String[] args) {
//InnerClass innerClass = new InnerClass();
OuterClass out = new OuterClass();
OuterClass.InnerClass innerClass2 = out.new InnerClass();
innerClass2.test();
}
}
静态内部类
静态内部类:定义在类的内部的一个类。但是由static来修饰的.
- 静态内部类对象如何拿到?
OuterClass.InnerClass innerClass = new OuterClass.InnerClass();
= new 外部类.静态内部类(); - 字节码文件和上面试一样的
- 在静态内部类当中,是不可以访问外部类的非静态数据成员的!!!!
因为,外部类的非静态数据成员 是依赖于外部类对象的
但是:如果非让你访问呢?????
思路:能不能给个外部类对象的引用???
class OuterClass {
public int data1 = 1;
public static int data2 = 2;
//静态内部类
static class InnerClass {
public int data3 = 3;
public static int data4 = 4;
public OuterClass out;
public InnerClass(OuterClass out) {
this.out = out;
}
public void test() {
System.out.println("InnerClass::test()");
//System.out.println(OuterClass.this.data1);不对的
System.out.println(out.data1);
System.out.println(data2);
System.out.println(data3);
System.out.println(data4);
}
}
}
public class Test2 {
public static void main(String[] args) {
OuterClass out = new OuterClass();
OuterClass.InnerClass innerClass = new OuterClass.InnerClass(out);
innerClass.test();
}
}
匿名内部类
匿名内部类:
在匿名内部类当中,使用的变量,或者是常量 或者是在整个过程当中 没有发生改变的量
//匿名内部类
class OuterClass {
public void sayHello() {
System.out.println("hello");
}
}
public class Test3{
public static void main(String[] args) {
int data1 = 10;
new OuterClass(){
@Override
public void sayHello() {
//data1 = 10;
//super.sayHello();
System.out.println("hhhhhh,匿内部类终于学完了!!!");
System.out.println(data1);
}
}.sayHello();
}
}
本地内部类
本地内部类:方法里面定义的类 没有意义。
public void func() {
class A {
//本地内部类
}
}
以上是关于总结java的泛型和内部类的主要内容,如果未能解决你的问题,请参考以下文章