Java基础

异常、反射、注解、内部类、泛型、序列化、复制

异常

* <p>The class {@code Exception} and any subclasses that are not also subclasses of {@link RuntimeException} are <em>checked exceptions</em>. Checked exceptions need to be declared in a method or constructor’s {@code throws} clause if they can be thrown by the execution of the method or constructor and propagate outside the method or constructor boundary.

Exception 源码

Exception 的所有子类,除了 RuntimeException 全部是 checked exceptionschecked exceptions 需要在方法或构造器使用throws声明,向上传播。

* An {@code Error} is a subclass of {@code Throwable} * that indicates serious problems that a reasonable application * should not try to catch. Most such errors are abnormal conditions. * The {@code ThreadDeath} error, though a “normal” condition, * is also a subclass of {@code Error} because most applications * should not try to catch it. * <p> * A method is not required to declare in its {@code throws} * clause any subclasses of {@code Error} that might be thrown * during the execution of the method but not caught, since these * errors are abnormal conditions that should never occur.

*

* That is, {@code Error} and its subclasses are regarded as unchecked * exceptions for the purposes of compile-time checking of exceptions.

{@code Error}是{@code Throwable}的子类,表示一个合理的应用程序不应该试图捕捉的严重问题。大多数这样的错误都是不正常的情况。{@code ThreadDeath}错误虽然是“正常”条件,但也是{@code Error}的子类,因为大多数应用程序不应该试图捕捉它。
一个方法不需要在它的{@code throws}子句中声明{@code Error}的任何子类,这些子类可能在方法执行过程中抛出,但不被捕获,因为这些错误是不应该发生的异常情况。
也就是说,为了在编译时检查异常,{@code Error}及其子类被视为未检查异常。

异常捕获,抛出,声明

使用try catch finally 捕获异常,使用throw手动抛出异常,使用throws在方法或构造器的声明上声明可能抛出的异常。

try catch finally 的执行顺序:在没有捕获到异常的情况下,执行try,finally两个块,如果try中有returnreturn分为两部分,计算return的值,把值传递回上层方法 ) ,则先 计算return的值 保存,再执行finally中的代码块,最后把值传递回上层方法; 在捕获到异常的情况下 ,执行catch,再执行finally

反射 reflect

反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。

JAVA反射机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键。

编译时类型和运行时类型

编译时的类型由声明对象时使用的类型来决定,运行时的类型由实际赋值给对象的类型决定。如:Person p=new Student(); 其中编译时类型为 Person,运行时类型为 Student。

如果编译时根本无法预知该对象和类属于哪些类,但是又需要调用该对象的运行时类型的方法,程序只能依靠运行时信息来发现该对象和类的真实信息,此时就必须使用到反射了。

反射机制的相关类

类名用途
Class类代表类的实体,在运行的Java应用程序中表示类和接口;
可以获取类的属性,方法等信息。
Field类代表类的成员变量(成员变量也称为类的属性),可以用来获取和设置类之中的属性值。 Java.lang.reflec
Method类代表类的方法 ,它可以用来获取类中的方法信息或者执行方法。 Java.lang.reflec
Constructor类代表类的构造方法 Java.lang.reflec

反射使用步骤

  1. 获取想要操作的类的 Class 对象,他是反射的核心,通过 Class 对象我们可以任意调用类的方法。
  2. 调用 Class 类中的方法,既就是反射的使用阶段。
  3. 使用反射 API 来操作这些信息。

获取 Class 对象的 3 种方法

  • Class.forName 使用 Class 类中的 forName() 静态方法( 最安全/ 性能最好)
  • Class clazz=Person.class; 调用某个类的 class 属性
  • Class clazz = instance.getClass(); 调用某个对象的 getClass() 方法

使用

Class clazz=Class.forName("tech.yiyehu.model.Person"); 
Method[] method=clazz.getDeclaredMethods(); 
Field[] field=clazz.getDeclaredFields(); 
Constructor[] constructor=clazz.getDeclaredConstructors(); 

对象创建

Java对象创建,使用new关键字调用类的构造方法。

关于类的加载与对象初始化:

利用Class 创建对象:

Class clazz=Class.forName("tech.yiyehu.model.Person");
//使用Class 的newInstance方法
Person p=(Person) clazz.newInstance(); 
//获取构造方法并创建对象 
Constructor c = clazz.getDeclaredConstructor(String.class,String.class,int.class);
Person p1=(Person) c.newInstance("name","1",20);  

注解

Java 注解用于为 Java 代码提供元数据。作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上可以用于这一目的。Java 注解是从 Java5 开始添加到 Java 的。看完这句话也许你还是一脸懵逼,接下我将从注解的定义、元注解、注解属性、自定义注解、注解解析JDK 提供的注解这几个方面再次了解注解(Annotation)

Annotation(注解)是 Java 提供的一种对元程序中元素关联信息和元数据(metadata)的途径和方法。Annatation(注解)是一个接口,程序可以通过反射来获取指定程序中元素的 Annotation对象,然后通过该 Annotation 对象来获取注解中的元数据信息

4 种标准元注解

@Target 修饰的对象范围。ElementType限制其范围

@Retention 定义被保留的时间长短。RetentionPolicy修饰其保留时间

@Documented 描述-javadoc

@Inherited 阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited 修饰的 annotation 类型被用于一个 class,则这个annotation 将被用于该class 的子类。

获取注解与元数据的方式

@PropertySource("classpath:swagger.properties")
public class Swagger2Docket {
}
Class clazz = Class.forName("com.example.demo.config.Swagger2Docket");
PropertySource propertySource = (PropertySource) clazz.getAnnotation(PropertySource.class);
System.out.println(propertySource.value()[0]);
运行结果:classpath:swagger.properties

JAVA 内部类

静态内部类

成员内部类

局部内部类( 定义在方法中的类 )

匿名内部类( 要继承一个父类或者实现一个接口、直接使用
new 来生成一个对象的引用 )

JAVA 泛型

类型擦除:

类型擦除指的是通过类型参数合并,将泛型类型实例关联到同一份字节码上。编译器只为泛型类型生成一份字节码,并将其实例关联到这份字节码上。类型擦除的关键在于从泛型类型中清除类型参数的相关信息,并且再必要的时候添加类型检查和类型转换的方法。 类型擦除可以简单的理解为将泛型java代码转换为普通java代码,只不过编译器更直接点,将泛型java代码直接转换成普通java字节码。 类型擦除的主要过程如下: 1.将所有的泛型参数用其最左边界(最顶级的父类型)类型替换。(这部分内容可以看:Java泛型中extends和super的理解) 2.移除所有的类型参数。

https://www.jianshu.com/p/36356dba3ee9

JAVA 序列化

JAVA 复制

赋值复制:引用

浅拷贝:复制了一个对象,但是属性引用的对象值复制了引用

深拷贝 复制了一个对象,属性引用的对象同样复制





除非注明,否则均为一叶呼呼原创文章,转载必须以链接形式标明本文链接

本文链接:http://www.yiyehu.tech/archives/2020/05/18/base-of-java

发表评论

电子邮件地址不会被公开。 必填项已用*标注