java基础知识学习 内部类、lambda表达式、反射(转载)

java基础知识学习 内部类、lambda表达式、反射

内部类

(内部类相对来说在开发中使用的相对较少,在开发客户端的时候可能会使用,但在web等开发的过程中使用不是很频繁,在使用的时候相对比较复杂)

为什么使用内部类?

内部类( inner class ) 是定义在另一个类中的类。 使用内部类的主要原因是:

  1. 内部类方法可以访问该类定义所在的作用域中的数据, 包括私有的数据
  2. 内部类可以对同一个包中的其他类隐藏起来。
  3. 当想要定义一个回调函数且不想编写大量代码时,使用匿名内部类比较便捷。

内部类的一些特点

  1. 内部类中声明的所有静态域都必须是 final。原因很简单。我们希望一个静态域只有一个实例, 不过对于每个外部对象, 会分别有一个单独的内部类实例。如果这个域不是 final, 它可能就不是唯一的。
  2. 内部类不能有 static 方法。
  3. 内部类的对象有一个隐式引用,他引用了实例化该内部对象的外围对象。通过这个指针,我们可以访问外围类对象的全部状态

内部类的特殊语法规则

  1. 使用外围类引用
    OuterClass.this.外围类的变量等
  2. 在外围类的作用域之外,引用内部类
    OuterClass.InnerClass

局部内部类

局部类不能用public或private访问说明符进行声明。它的作用域被限定在声明这个局部类的块中。局部类可以对外部世界完全的隐藏起来。

局部类还可以访问它的作用域范围内的局部变量,不过,那些局部变量必须事实上为final。但是我们可以通过使用数组的方式来更改某些值。

匿名内部类

将局部内部类的使用再深人一步。 假如只创建这个类的一个对象,就不必命名了。这种类被称为匿名内部类(anonymous inner class)。

在这里插入图片描述

由于构造器的名字必须与类名相同,而匿名类没有类名,所以,匿名类不能有构造器。取而代之的是,将构造器参数传递给超类的构造器。

静态内部类

有时候,使用内部类指示为了把一个类隐藏在另一个类的内部,并不需要内部类引用外围类对象。为此,可以将内部类声明为static,以便取消产生的引用。

lambda表达式

lambda表达式是一个可传递的代码块,可以再以后执行一次或多次。

lambda表达式的语法

lambda表达式就是一个代码块,以及必须传入代码的变量规范。
在这里插入图片描述
参数,箭头以及一个表达式是lambda表达式的形式之一。
如果代码要完成的计算无法放在一个表达式中,就可以像写方法一样,把这些代码放在{}中,并包含显示的return语句。
在这里插入图片描述
即使lambda表达式没有参数,仍然要提供空括号,就像无参数方法一样。
在这里插入图片描述
如果可以推导出这个表达式的参数类型,则可以忽略其类型
在这里插入图片描述
如果方法只有一个参数,而且这个参数的类型可以推导得出,那么深知还可以省略小括号。
在这里插入图片描述
不需要指定lambda表达式的返回类型,其返回类型总是会由上下文推到得出。

函数式接口

对于只有一个抽象方法的接口,需要这种接口的对象时,就可以提供一个lambda表达式。这种接口成为函数式接口。

反射

能够分析类能力的程序成为反射。反射机制的功能及其强大,反射可以用来:

  1. 在运行时分析类的能力
  2. 在运行时查看对象,例如编写一个toString方法供所有类使用。
  3. 实现通用的数组操作代码
  4. 利用Method对象

class类对象

Student student = new Student();
获取class对象的三种方式
1.Student.class;
2.student.getClass();
3.Class.forName(“Student”);
可以通过e.getClass().newInstance创建一个对象实例
Class.getName()可以获取某个类型的名字
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

虚拟机为每个类型管理一个Class对象。因此,可以利用==运算符实现两个类对象比较的操作。

利用反射分析类的能力

在java.lang.reflect包中有三个类Field、Method和Constructor分别用于描述类的域、方法和构造器。
这三个类都有一个叫做getName()的方法,用来返回项目的名称。
这三个类还有一个交getModifiers的方法,他将返回一个整形数值,用来描述public、private等这样的修饰符。

常用的一些API

//返回一个包含 Field 对象的数组, 这些对象记录了这个类或其超类的公有域。
Field[] getFields() 
//返回包含 Field 对象的数组, 这些对象记录了这个类的全部域。 如果类中没有域, 或者 Class 对象描述的是基本类型或数组类型, 这些方法将返回一个长度为 0 的数组。
Filed[] getDeclaredFie1ds()

//返回所有的公有方法, 包括从超类继承来的公有方法
Method[] getMethods()
//返回这个类或接口的全部方法, 但不包括由超类继承了的方法
Method[] getDeclareMethods()

//返回包含 Constructor 对象的数组, 其中包含了 Class 对象所描述的类的所有公有构造器
Constructor[] getConstructors()
//返回包含 Constructor 对象的数组, 其中包含了 Class 对象所描述的类的所有构造器
Constructor[] getDeclaredConstructors()


//返回一个用于描述构造器、 方法或域的修饰符的整型数值。使用 Modifier 类中的这个方法可以分析这个返回值。
int getModifiers( )
//返冋一个用于描述构造器、 方法或域名的字符串。
String getName( )

//返回 obj 对象中用 Field 对象表示的域值。
Object get( Object obj )
//用一个新值设置 Obj 对象中Field 对象表示的域
void set(Object obj ,Object newValue)

//调用这个对象所描述的方法, 传递给定参数,并返回方法的返回值。对于静态方法,把 null 作为隐式参数传递。 在使用包装器传递基本类型的值时, 基本类型的返回值必须是未包装的。
public Object invoke (Object implicitParameter,Object[] explicitParamenters)


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

反射机制的默认行为受限于java的访问控制。然而,如果一个Java程序没有受到安全管理器的控制、就可以覆盖访问控制。
为了达到这个目的,需要调用setAccessible 方法

 

原文链接:https://blog.csdn.net/weixin_44577413/article/details/113888935

posted @ 2021-02-24 01:04  八佰山兵上北坡  阅读(117)  评论(0编辑  收藏  举报