如果某个方法不能按照正常的途径完成任务时,就可以通过另一种路径退出方法。在这种情况下会抛出了一个封装错误信息的对象。此时,这个方法立刻退出同时不返回任何值。另外调用这个方法的其他代码也无法继续执行,异常处理机制会将代码执行交给异常处理器。
异常分类Throwable 是java语音中所有错误或异常的超类。下一层分为Error和Exception
Error: 是指java运行时系统的内部错误和资源耗尽错误。应用程序不会抛出该类对象。如果出现了这样的错误,除了告知用户,剩下的就是尽力使程序安全的中止。
Exception: 运行时异常(RuntimeExecption),检察时异常(CheckedException)
RuntimeException: 如:NullpointerException、ClassCastException。
CheckedException:一般是外部错误,这种异常发生在编译阶段,java编译器会强制程序补货次异常.(I/O错误导致的IOException)
- 遇到问题向上抛出 throw(函数内),throws(函数),系统自动抛出异常
在程序运行时候可以改变其结构,新的函数可以引进,已有的函数可以被删除等结构上的变化。比如常见的javascript,python就是动态语音。从反射角度说java属于半动态语音。
反射机制概念在运行状态中,对于任意一个类都能够知道这个类所有的属性和方法;对于任意一个对象,都能够调用它的任意一个方法。这种动态获取信息以及动态调用方法的功能能成为java语言的反射机制
反射的应用场景-
编译时类型和运行时类型。编译形类型是由声明对象时实用的类型决定,运行时类型由实际赋值给对象的类型决定。如:
Person p = new Student()
其中编译时类型为Person,运行时类型为Student -
编译时类型无法获取具体方法
程序在运行时还可能接收到外部传入的对象,该对象编译时类型为object,但是需要程序有需要调用该对象的运行时类型的方法。为解决这些问题,程序需要在运行时发现对象和类的真实信息。然后,如果编译时根本无法预知该对象和类属于哪些类,程序只能依靠运行时信息来发现该对象和类的真实信息,此时就必须用到反射。
反射API用来生成JVM中的类,接口或则对象的信息
- Class 类: 反射的核心类,可以获取类的属性、方法等信息
- Field类:表示成员变量,可以用来获取和设置类之中的属性
- Method类:表示类中的方法,可以用来获取类中的方法信息或执行方法
- Constructor: 表示类的构造方法
- 获取想要操作类的class对象,反射的核心。通过class对象我们可以任意调用类的方法
- 调用class类中的方法,就是反射的使用的使用阶段
- 使用反射API来操作
- 调用某个对象的getClass()方法 Person p = new Person() Class clazz = p.getClass();
- 调用某个类的.class属性来获取该类对应的class对象 Class clazz = Person.class;
- 使用Class 类中的forName()静态方法(最安全/性能最好)
Class clazz = Class.forName(“类的全路径”)
- Class 对象的newInstance() ,需要有默认的空参构造器
- 先使用Class对象获取制定的Constructor对象,再调用Constructor对象的newInstance()方法来创建Class对象对应类的实例,通过这种方法可以选定构造方法创建实例
####基本概念
概念:Annotation 是java提供的一种对元程序中元素关联信息和元数据的途径和方法。Annotation是一个接口,程序可以通过反射来获取Annotation对象,然后通过Annotation对象来获取注解中的元数据信息。
元注解的作用是负责注解其他注解,对其他annotation类型做说明
- @Target 修饰对象的范围 说明了Annotation所修饰的对象范围,可以与packages,types,类型成员(方法,构造器等),方法参数和变量
- @Retention 定义被保留的时间长短 Retention定义了该Annotation被保留的时间长短:表示需要在什么级别保存注解信息,用于描述注解的生命周期,比如:SOURCE(源文件)/Class(class文件)/RUNTIME(运行时)
- @Documented javadoc
- @Inherited 阐述某个被标注的类型的是被继承的
注解比注释有用来读取的方法,java se扩展了反射机制的api,帮助程序员快速的构造自定义注解处理器,下面实现一个注解处理器:@interface
JAVA 内部类java类中不仅可以定义变量和方法,还可以定义类,这样定义在类内部的类就是内部类。根据定义方式不同,内部类分为静态内部类、成员内部类、局部内部类、匿名内部类四种。
静态内部类定义在类内部的静态类,就是静态内部类
- 静态内部类可以访问外部类的所有的静态变量和方法,即使是private方法也可以
- 静态内部类和一般类一样,可以定义静态变量、方法、构造方法等
- 其他类使用静态内部类需要使用外部类.静态内部类方式进行构造。
- Java集合类HashMap内部就有一个静态内部类Entry。Entry是HashMap存放元素的抽象,HashMap内部维护Entry数组用来存放元素,但是Entry对使用者是透明的,像这种和外部类关系密切的,且不依赖外部类实例的,都可以使用静态内部类。
定义在类内部的非静态类就是成员内部类。成员内部类不能定义静态方法和变量(final 修饰的除外)。这是因为成员内部类是非静态的,类初始化时候先初始化静态成员,如果允许成员内部类定义静态变量,那么成员内部类的静态变量初始化顺序是有歧义的
局部内部类定义在方法中的类,就是局部类。如果一个类只在某个方法中使用,则可以考虑使用局部类。
匿名内部类必须继承一个父类或者实现一个接口,当然也仅能只继承一个父类或者实现一个接口。同时也是没有class关键字,因为匿名内部类直接使用new来生成一个对象的引用
JAVA 泛型泛型提供了编译时类型安全检测的机制,该机制允许程序员在编译时检测到非法的类型。泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。比如我们要写一个排序方法,能够对多种类型数据进行排序。
泛型方法public static void print(E[] array)
泛型类泛型类的声明和非泛型类声明类似。和泛型方法一样,泛型类的类型参数部分也包含一个或多个类型参数,参数用逗号隔开。一个泛型参数,也被称为一个泛型变量。 public class Box{T t}
类型通配符?类型通配符一般是使用?代替具体的类型参数。例如List> 在逻辑上是List,List 等所有List<具体类型实参>的父类
类型擦除JAVA中泛型基本上都是在编译器这个层次实现的。在生成的java字节码中是不包含泛型中的类型信息。使用类型上届替换这个类,比如Oject
JAVA 序列化(创建可复用的java对象) 保存/持久化对象及其状态到内存或者磁盘Java平台首先允许我们在内存中创建可复用的Java对象,但一般情况下,只有当jVM处于运行时,这些对象才是存在的,即这些对象的生命周期不会比JVM的生命周期更长。但在现实应用中,就可能要求在JVM停止运行之后能够保存(持久化)指定对象,并在将来重新读区被保存的对象。Java对象序列化就能帮助我们实现该功能。
序列化对象以字节数组保持-静态成员不保存使用Java对象序列化,在保存对象时,会把其状态保存为一组字节,在未来,再将这些字节组装成对象。必须注意地是,对象序列化保存的事对象的状态,即它的成员变量。由此可知,对象序列化不会关注类中的静态变量。
序列化用户远程对象传输除了在持久化对象时会用到对象序列化之外,当使用RMI(远程方法调用),或在网络传递对象时,都会用到对象序列化。Java序列化API为处理对象序列化提供了一个标准机制,
Serializable实现序列化在java中,只要一个类实现了java.io.Serializable接口,那么它就可以被序列化
序列化ID虚拟机是否允许反序列化,不仅取决于类路径和功能代码是否一致,一个非常重要的一点是两个类的序列化id是否一致。
序列化并不保存静态变量
序列化子父类:如果要想将父类也序列化,需要让父类也实现Serializable接口。
Transient关键字阻止该变量被序列化到文件中。
三种复制方式:直接赋值、深拷贝、浅拷贝
直接赋值复制A a1 = a2,复制的是饮用
浅复制复制引用但是不复制引用的对象,创建一个新对象,然后将当前对象的非晶态字段复制到该新对象,如果字段是值类型的,那么对该字段进行复制,如果是引用对象,则复制引用但是不复制引用对象。
深复制深拷贝不仅复制对象本身,而且复制对象包含的引用指向的所有对象。
可以通过序列化实现深拷贝,读取后再解析。



