20201018冯强

学习总结:

1.反射

public final class Class implements java.io.Serializable, GenericDeclaration, Type, AnnotatedElement

Class 是一个泛型类,如 String 就是一个 Class 对象,表示的是 Class

2.获取class

2.1 通过Object 的getClass() 获取

Util util = new Util();//Util对象 
Class cl = util.getClass();//获取对应的Class对象

2.2通过类的class 属性(域)

Class cl1 = Util.class;

2.3通过Class 类的forName() 获取

forName(String name) 中 name 指要获取的 Class 类的 全限定类名 ,此方法会抛出一个ClassNotFoundException 异常,如果传的参数不是全限定类名或正确的全限定类名都会抛出此异常。

Class cl2 = Class.forName("java.lang.String");//正确写法 
Class cl3 = Class.forName("String");//错误写法,会抛异常

2.4 getName()

Class cl2 = Class.forName("java.lang.String");//正确写法 
System.out.println(cl2); //class java.lang.String 
String name = cl2.getName(); 
System.out.println(name);//java.lang.String

2.5 获取构造方法

public Constructor getConstructor(Class<?>… parameterTypes)通过参数来获取某一个 public 构造方法,其中 parameterTypes 是构造方法中参数的类型的 Class ,是一个可变参表示可以不传,不传就是无参构造

package com.itlaobing.demo.reflect;
import java.lang.reflect.Constructor;
public class ClassTest { public static void main(String[] args) throws NoSuchMethodException, SecurityException { 
    Class<Student> cl = Student.class;
    Constructor<Student> constructor = cl.getConstructor();
}
                       }

此方法会抛出两个异常:

  1. java.lang.NoSuchMethodException 表示没有符合要求的构造方法一般抛出此异常是因为参数传递不正确

  2. java.lang.SecurityException 如果安全管理器 ,S存在,并且调用者的类加载器是不一样或类加载器的当前类和调用的祖先 s.checkPackageAccess()拒绝访问包这个类的public Constructor<?>[] getConstructors() 此方法返回 Class 对象中的所有 public 构造方法

3.创建对象

通过反射来创建对象有两种方式使用 Class 对象的 newInstance() 方法创建对象

使用 Constructor 对象创建对象

使用 newInstance() 要注意, Class 对象中必须要有且可访问的无参构造方法(默认构造)。

示例一:使用 Class 对象的 newInstance() 方法

package com.itlaobing.demo.reflect;
public class ClassTest7 {
    public static void main(String[] args) throws InstantiationException, IllegalAccessException {
        Class<Student> cl = Student.class;//获取对象,注意声明泛型 
        Student stu = cl.newInstance();//创建对象,会调用无参构造 
        System.out.println(stu); 
    }
}

示例二:使用 Constructor 对象的 newInstance(args) 方法

Class<Student> cl = Student.class;//无参构造 
Constructor<Student> cons = cl.getConstructor(); 
Student stu1 = cons.newInstance(); 
System.out.println(stu1); //使用有参构造 
Constructor<Student> cons1 = cl.getConstructor(String.class, double.class, String.class); Student stu2 = cons1.newInstance("张三丰", 100.01, "男");
System.out.println(stu2);

newInstance 方法的参数是可变参,对应我们 getConstructor 方法的参数

4.访问类的域(属性)

java.lang.reflect.Method 类提供了操作对象的方法。

public int getModifiers() 获取修饰符

public String getName() 获取方法名

public int getParameterCount() 获取参数个数

package com.itlaobing.demo.reflect;

public class ClassTest7 {

public static void main(String[] args) throws InstantiationException,

IllegalAccessException {

Class cl = Student.class;//获取对象,注意声明泛型

Student stu = cl.newInstance();//创建对象,会调用无参构造

System.out.println(stu);

}

}

Class cl = Student.class;

//无参构造

Constructor cons = cl.getConstructor();

Student stu1 = cons.newInstance();

System.out.println(stu1);

//使用有参构造

Constructor cons1 = cl.getConstructor(String.class, double.class,

String.class);

Student stu2 = cons1.newInstance("张三丰", 100.01, "男");

System.out.println(stu2);

public Class<?>[] getParameterTypes() 获取参数类型

public Class<?> getReturnType() 获取返回值类型

public Object invoke(Object obj, Object… args) 执行方法,返回值是方法的返回值

public String toString() 以字符串形式返回方法信息

4.使用Array类动态创建和访问数组

java.lang.reflect.Array 提供静态方法来动态创建和访问Java数组

package com.itlaobing.demo.reflect;
import java.lang.reflect.Array;
public class ArrayTest { 
    public static void main(String[] args) {
        Object array = Array.newInstance(int.class, 2);
        System.out.println(Array.get(array, 0)); //0 
        Array.set(array, 0, 1); Array.setInt(array, 1, 2);
        for (int i = 0; i < 2; i++) { 
            System.out.println(Array.get(array, i)); 
        } 
    } 
}

5 注解

注解是 JDK 1.5 的特性

注解是 java 代码中的特殊标记,是类的组成部分,可以携带一些特殊信息

注解可以加在包、类、字段、方法、方法参数以及局部变量上。

注解是给编译器或 JVM 看的,编译器或 JVM 可以根据注解来完成相应的功能。

注解的形式是以 @ 符号开头,我们已经见过的注解有

@Override / @SupperssWarnings("serial") 等

Java的注解可以分为四类:

\1. 由编译器使用的注解,例如:

@Override :让编译器检查该方法是否正确地实现了覆写(重写)

@SuppressWarnings :告诉编译器忽略此处代码产生的警告

这类注解不会被编译进入 .class 文件,它们在编译后就被编译器去掉了

\2. 生成文档。这是最常见的,也是 java 最早提供的注解。常用的有 @see 、 @param 、 @return 、

@author 、 @version 等,就是告诉 Javadoc 工具在生成帮助文档时把作者姓名和版本号等也标

记在文档中

\3. 会被编译器编译到 .class 文件中的注解,这类注解只被一些底层库使用,一般我们不必自己处理

\4. 在程序运行期能够读取的注解,它们在加载后一直存在于 JVM 中,这也是最常用的注解。比如:

@Deprecated (废弃)

包 java.lang.annotation 中包含所有定义自定义注解所需用到的注解和接口。

java.lang.annotation.Annotation 是所有所有注释类型扩展的公共接口。此接口本身并不定义注释

类型

6.定义注解

public @interface 注解名{ }
如:定义一个名为Student的注解 
    public @interface Student { }

其中数据类型可以是:

八种基本数据类型

String类型,Class类型,枚举类型,注解类型

以上所有类型的一维数组

标签

评论

this is is footer