?通配符来处理泛型中接受的类型问题,表示可以接受任意类型
?extends类:设置泛型上限:例如:?extends Number,表示只能够接受数字或其子类
?super类:设置泛型下限:例如:?super String,表示只能设置String或其父类Object
?通配符来处理泛型中接受的类型问题,表示可以接受任意类型
?extends类:设置泛型上限:例如:?extends Number,表示只能够接受数字或其子类
?super类:设置泛型下限:例如:?super String,表示只能设置String或其父类Object
可变参数public void med(int ... data){}
其中的...实际是数组表示任意多个int,也可以一个不传
public void med(string a,int ...data){}
一个方法只能有一个可变参数
Thread与Runnable的区别
首先从形式上来讲明显使用Runable实现多线程会更好,但是Thread与Runnable之间也存在着一些联系,首先类观察一下Thread类的定义形式。
Thread类是Runable是的之类,Thread应该也有方法覆写
Thraed类是功能是进行线程的启动,但是如果一个类继承Thread类,进行单线程
java又提供另外一个实现模式:Runable
@FunctionalInterface
public interface Runnable{
public void run();
}
可以发现在接口里面同时存在有一个run()方法,这一点和Thread是相同的。因为是接口的子类必须实现父类的方法。
MyThread类不再是Thread类,解决了但继承问题,但是没有了start()方法,需要关注Thread类提供的构造方法。
构造方法:public Thread(Runnable target),可以接收Runnable的接口对象,通过Thread可以启动
范例:启动多线程。
多线程的启动都是Thread类的start()方法。
通过匿名内部类
java的第一大特色:多线程编程
进程:操作系统之中程序的执行周期是一个进程,程序一定使用电脑的Io,CPU,内存。DOS系统时代只能执行一个进程。
程序是轮流抢占cpu资源,
一块资源在同一个时间段上可能有多个进程交替执行,在同一个时间点上只会有一个进程执行。而线程是在进程的基础上的进一步划分,也就是说线程是比进程更小的单位。很明显线程的启动所花费的时间是短的,也就说进程要比线程慢。那么java本身是一个多线程的编程语言,所以执行的性能比较强。
进程消失了线程肯定会消失。
java的多线程体现在哪里呢?
高并发:访问量的内存不够用。
如果想实现多线程,必须有一个前提,有一个线程的执行主类。
线程的主类 main()
多线程的主类
main 多线程的主类(启动方法)
如果想实现一个多线程的主类,有两类途径:
继承一个Thread类
实现Runnable ,Callable接口
继承Thread类实现多线程
java.lang.Thread是一个线程操作的核心类。如果想定义一个线程的主类,继承Thread类,后覆写run()方法;
定义一个线程的实体类
当线程有了主体类后,产生对象,调用run方法。多线程给进程执行时相同,应该是交替执行,应该启动主类中的start()方法;
启动多线程 public void start(),启动run
启动了start发现了线程进行了交替执行。
为什么要通过start()方法来调用run()方法
源代码在jdk的安装目录下。
首先在本程序中发现该方法会抛出一个异常'IlligalException',常用方法应该使用throws声明,或者直接在方法中进行try。。。catch。
这个线程只有多次启动的时候才抛出异常。
而后可以发现在start()方法中调用了一次start0方法,而这个方法是一个只声明而为实现,用native关键字进程修饰,调用了本系统函数。
内建函数式接口
Lamdba简化了方法引用,Lamdb核心在于函数接口,接口的核心是只有一个方法。函数式编程里面只有四种接口。(java.until.function)
功能性函数式接口:public interface Function<T,R>{public R apply(T t);};
供给型函数接口:Interface Supplier<T> {public T get ();};
消费型函数式接口:pulic interface Consumer<T> {public void accept(T t);}
段言型函数式接口:public interface Predicate<T>{boolean test(T t);}
使用功能性:你输入一个数据,然后进行输出,实际上所有的函数与式函数都有扩展
Consumer<String> cons=System.out::println;
cons.accept("Hello");
Supplier<String>sup="hello"::toUpperCase;
System.out.println(sup.get());
Predicate<String> pre="##hello"::startswith;
System.out.println(pre.test("##"));
引用,本质就是别名,方法类型的引用
1 引用静态方法:类名称::static方法名称;
2引用某个对象的方法:实例化对象::普通方法
3引用某个特定类的方法:类名称::普通方法
4引用构造方法:类名称::new
将相当于提供别名;
引用某个对象的方法
interface IUtil<R>{
public R zhuanhuan();
}
public class TestDemo{
public static void main(String[] args){
IUtil<String> iu="hello"::toUpperCase;
System.out.println(iu.zhuanhuan());
}
}
lambda表达式
haskell
函数式编程
传统的面向对象
采用匿名内部类,减少了一个文件,对于此类操作有了更简化。
面向对象的要求在于:结构必须非常完整。
但是如果想使用函数式编程有一个前提:接口必须有一个方法,如果有两个方法,则不用函数式编程。因此要想用一个函数式编程就出现了一个新的注解@FunctionalInterface。
实际上以上的语法形式
()->
函数式编程的使用
只能有一个方法
@FunctionalInterface
interface IMessage{
public void print();
}
如果有多行,直接用{}
在之前接触到的是1.5~1.7
1.8接口新特性
接口加强
接口在使用的时候缺个方法,
接口只有方法的声明,而没有方法实现。
将接口将无法实现,
可以使用default来定义普通方法,需要通过对象调用。
可以使用static来定义静态方法,通过类名.进行访问。
接口可以被多实现,继承只能被继承一次。
建议不要用,因为时间一长,许多的支持会出现问题,此操作不属于标准设计,它属于挽救设计。
压制警告:@SuppressWaring
在调用了某些操作,出现了问题,对开发者进行警告。
可以在对象上也可以在主方法上。
这三种是jkd默认的
声明过期处理:@Deprecated
过期的声明,表示此方法不建议使用了,但是即使使用了也不会出现错误。
这种操作一般出现在平台支持的go
准备覆写@override
方法覆写:发生在继承关系之中,子类定义了与父类方法名相同,相同的参数列表,相同的返回值类型,不能比父类具有严格的访问控制权限。
范例:
可以用一个注解()用来判断父类的方法是否被覆写,如果没有成功覆写,则认为是语法错误。当覆写的方法正确的时候,则不会发生错误。
annotation
可以说是整个jdk发展的一项重要技术
1 在进行软件项目开发过程中,会将所有使用到的第三方的信息,和程序有关的操作全部都写在程序里面。
-如果服务器的地址更换了,需要更改的程序代码就更加庞大了。
2使用配置文件,程序在运行的时候要通过配置文件读取相关的配置操作
当使用配置文件时,代码维护方便了,但配置文件比较多的时候,会造成开发人员的眩晕,将配置文件写回到程序中。这样就形成了注解
配置文件依然存在,只是少了,
三个内置注解:@Override,@Deprecated
@SuppressWarning
枚举只有几个对象
定义枚举其他结构
虽然枚举等同于多例,多例可以定义多个属性和方法,从概念上只能说产生了若干个对象,在枚举更强大的方案:可以在枚举中定义属性,方法,或实现接口
//如果定义很多内容,枚举对象必须写在第一行
枚举本身可以实现接口
Enum类
只是对一种类型的包装:使用enum关键字定义的枚举类本质上就相当于一个class定义的类,继承了class.lang.enum
多例与枚举最大的区别是:枚举具有value的方法。
enum 构造方法:protected Enum(String name,int ordinal())
enum和Enum的区别
enum是一个关键字,使用enum定义的枚举类,继承了Enum抽象类
枚举
多例设计模式:构造方法私有化,类内部要实现多个实例化对象。后面通过static方法返回。
枚举就是高级的多例设计模式。
泛型方法
泛型方法不一定定义在泛型类或者接口里面,也可以单独定义。
<T>表示泛型标记的声明
public static <T> T[] fun(T ... args){
return args;
}
泛型接口
对接口的实现子类有两种
1 继续使用泛型
对类继续使用泛型
2 在子类实现接口的时候,给出具体的类型
在接口的时候直接添加具体的类型。
以后所编程的一定要使用泛型接口