目录
1.注解
1.1 概念
它可以增强我们的java代码,同时利用反射技术可以扩充实现很多功能。广泛用于三大框架底层。传统通过xml文本文件声明方式,现在开发基于注解方式,代码量少,框架可以根据注解去自动生成很多代码,从而减少代码量,程序更易读。
1.2 分类
JDK自带注解
元注解
自定义注解
1.3 JDK注解
@Override 表示当前方法覆盖了父类的方法
@Deprecated 表示方法已经过时,方法上有横线,使用时会警告
@SuppressWarnings 表示关闭一些警告信息(通知java编译器忽略特定的编译警告)
@SafeVarargs jdk1.7出现,堆污染,不常用
@FunctionallInterface jdk1.8出现,配合函数式编程拉姆达表达式,不常用
1.4 元注解
@Target 注解用在哪里:类上、方法上、属性上
@Retention 注解的生命周期:源文件中、class文件中、运行中
@Inherited 允许子注解继承
@Documented 生成javadoc时会包含注解,不常用
@Repeatable注解为可重复类型注解,可以在同一个地方多次使用,不常用
2.反射
2.1 概念
Reflection(反射) 是 Java 程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查,或者说“自审”,也有称作“自省”。反射非常强大,它甚至能直接操作程序的私有属性。我们前面学习都有一个概念,private的只能类内部访问,外部是不行的,但这个规定被反射赤裸裸的打破了。反射就像一面镜子,它可以在运行时获取一个类的所有信息,可以获取到任何定义的信息(包括成员变量,成员方法,构造器等),并且可以操纵类的字段、方法、构造器等部分。
2.2 为什么需要反射
在开发的世界里,spring就是专业的组织,它来帮我们创建对象,管理对象。我们不在new对象,而直接从spring提供的容器中beans获取即可。Beans底层其实就是一个Map<String,Object>,最终通过getBean(“user”)来获取。而这其中最核心的实现就是利用反射技术。
总结一句,类不是你创建的,是你同事或者直接是第三方公司,此时你要或得这个类的底层功能调用,就需要反射技术实现。有点抽象,别着急,我们做个案例,你就立马清晰。
2.3 反射Class类对象
Class.forName(“类的全路径”);
类名.class
对象.getClass();
3.内部类
3.1 概念
如果一个类存在的意义就是为指定的另一个类,可以把这个类放入另一个类的内部。就是把类定义在类的内部的情况就可以形成内部类的形式。A类中又定义了B类,B类就是内部类。B类可以当做A类的一个成员看待。
3.2 特点
①.内部类可以直接访问外部类中的成员,包括私有成员
②.外部类要访问内部类的成员,必须要建立内部类的对象
③.在成员位置的内部类是成员内部类
④.在局部位置的内部类是局部内部类
3.3 成员内部类
被private修饰
package cn.tedu.inner;
//测试内部类被private修饰
public class Test5_InnerClass2 {
public static void main(String[] args) {
//TODO 创建内部类对象,并执行show()
// Outer2.Inner2 oi = new Outer2().new Inner2();//报错,Inner2已经被private了
//3,测试被private的内部类的资源能否执行!
new Outer2().test();
}
}
class Outer2{
//2,如果想要访问private的内部类,可以访问外部类提供的对应方法
public void test() {
//访问内部类方法
new Inner2().show();
}
//位置在类里方法外--成员内部类
//1,内部类可以被private修饰,但是外界无法直接创建对象了!
private class Inner2{
public void show() {
System.out.println("Inner2.show()");
}
}
}
被static修饰
package cn.tedu.inner;
//测试内部类被static修饰
public class Test6_InnerClass3 {
public static void main(String[] args) {
// 创建内部类对象测试show()
// Outer3.Inner3 oi = new Outer3().new Inner3();//报错,原因是Inner3是静态的内部类
Outer3.Inner3 oi = new Outer3.Inner3();//Outer3.Inner3通过类名.调用类中的静态资源
oi.show();
Outer3.Inner3.show2();//调用静态内部类里的静态方法
}
}
class Outer3{
//1,内部类被static修饰--随着类的加载而加载,会造成内存资源浪费,并不常用!
static class Inner3{
public void show() {
System.out.println("Inner3.show()");
}
static public void show2() {
System.out.println("Inner3.show2()");
}
}
}
3.4 局部内部类
package cn.tedu.inner;
//测试局部内部类
public class Test7_InnerClass4 {
public static void main(String[] args) {
//创建对象测试test()的执行
Outer4 out = new Outer4();
out.show();
}
}
class Outer4{
public void show() {
//位置如果在方法里--局部内部类--减少类的作用范围,提高效率节省内存,不常见!
class Inner4{
public void test() {
System.out.println("Inner4.test()");
}
}
//触发内部类的功能
new Inner4().test();
}
}
3.5 匿名内部类
匿名内部类属于局部内部类,并且是没有名字的内部类。
package cn.tedu.inner;
//测试匿名内部类
public class Test8_InnerClass5 {
public static void main(String[] args) {
new Hello() {// 匿名对象,本身接口不能new,这里new Hello()匿名对象,就相当于Hello接口的实现类
// 匿名内部类
@Override
public void save() {
System.out.println("save()..");
}
@Override
public void update() {
System.out.println("update()..");
}
}.update();// 触发指定的方法
new Hello2() {//抽象类的匿名内部类
@Override
public void show() { }
}.show();
new Animal() {//普通类的匿名内部类
@Override
public void eat() { }
};
}
}
//TODO 创建匿名对象+匿名内部类测试
class Animal{
public void eat() {}
}
abstract class Hello2 {
abstract public void show();
public void delete() { }
}
// 定义接口
interface Hello {
void save();
void update();
}