注解
内置注解
-
@Override: 重写超类的方法
-
@Deprecated: 弃用
-
@SuppressWarnings: 抑制编译时的警告信息
元注解
-
@Target: 注解的范围
-
@Retention: 注解的生命周期
-
SOURCE<CLASS<RUNTIME
-
-
@Document: 注解将包含在javadoc中
-
@Inherited: 子类可以继承父类的注解
import java.lang.annotation.*;
public class TestStart {
//没有参数
反射
-
Reflection是java视为动态语言的关键
-
反射机制允许程序在执行期间借助Reflection API获取任何类的内部信息,并可以直接操作任意对象的内部属性及方法
-
一个类只有一个Class对象
-
反射是实例对象获取完整的类的信息
-
优缺点
-
动态创建对象和编译,具有很高的灵活性
-
对性能有影响,因为反射基本是一种解释操作,得告诉JVM我们需要做什么才能满足我们的要求
-
public class TestReflection {
public static void main(String[] args) throws ClassNotFoundException {
//通过Class.forName反射获取类
Class c1 = Class.forName("User");
System.out.println(c1);
//一个类只有一个Class对象,证明
Class c2 = Class.forName("User");
Class c3 = Class.forName("User");
Class c4 = Class.forName("User");
System.out.println(c1.hashCode());
System.out.println(c2.hashCode());
System.out.println(c3.hashCode());
System.out.println(c4.hashCode());
//每个类都继承Object,所以都有getClass()获取Class对象
User user = new User();
Class c5 = user.getClass();
System.out.println(c5);
System.out.println(c5.hashCode());
}
}
class User{
private Integer id;
private String name;
public User() {
}
public User(Integer id, String name) {
this.id = id;
this.name = name;
}
public void setId(Integer id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public Integer getId() {
return id;
}
public String getName() {
return name;
}
反射获取类的方式
public class TestReflection_methods {
public static void main(String[] args) throws ClassNotFoundException {
Student student = new Student("小红");
//方式一: 通过实例获取
Class c1 = student.getClass();
System.out.println(c1.hashCode());
//方式二: 通过.class获取
Class c2 = Student.class;
System.out.println(c2.hashCode());
//方式三: 通过Class.forName
Class c3 = Class.forName("Student");
System.out.println(c3.hashCode());
//方式四: 只有基本包装类才有
Class c4 = Integer.TYPE;
System.out.println(c4.hashCode());
//获取父类的Class
Class c5 = c1.getSuperclass();
System.out.println(c5.hashCode());
}
}
class Person{
String name;
}
class Student extends Person{
public Student(String name){
this.name = name;
}
}
import java.lang.annotation.ElementType;
public class TestReflection_all {
public static void main(String[] args) {
Class c1 = Integer.class; //基本类型
Class c2 = String[].class; //一维数组
Class c3 = int[][].class; //二维数组
Class c4 = Class.class; // Class
Class c5 = ElementType.class; //枚举
Class c6 = Override.class; //注解
Class c7 = Comparable.class;//接口
Class c8 = Object.class; // 类
Class c9 = void.class;//void
System.out.println(c1);
System.out.println(c2);
System.out.println(c3);
System.out.println(c4);
System.out.println(c5);
System.out.println(c6);
System.out.println(c7);
System.out.println(c8);
System.out.println(c9);
}
}
获取类运行时的结构
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class TestReflection_get {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
Class user = Class.forName("User");
//获取类的名字
System.out.println(user.getName());
System.out.println(user.getSimpleName());
//获取字段
Field[] fields = user.getFields(); //获取public修饰的属性
for (Field field : fields) {
System.out.println(field);
}
fields = user.getDeclaredFields();//获取所有的属性
for (Field field : fields) {
System.out.println(field);
}
//获取指定的字段
Field name = user.getDeclaredField("name");
System.out.println(name);
//获取构造器
Constructor[] constructors = user.getConstructors(); //获取public的构造器
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
constructors = user.getDeclaredConstructors();//获取所有的构造器
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
//获取指定的构造器
Constructor constructor = user.getConstructor(Integer.class, String.class);
System.out.println(constructor);
//获取方法
Method[] methods = user.getMethods();//获取public的方法
for (Method method : methods) {
System.out.println(method);
}
methods = user.getDeclaredMethods();//获取所有的方法
for (Method method : methods) {
System.out.println(method);
}
//获取指定的方法
Method method = user.getMethod("setName",String.class);
System.out.println(method);
}
}
获取实例(两种)
-
newInstance()
-
类必须有一个无参构造
-
类的构造器权限需能访问
-
-
通过getDeclaredConstructor()获取构造器,再向构造器形传递一个对象数组进去,最后Constructor实例化对象
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test_Instance {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
//反射实例化(无参构造)
Class user = Class.forName("User");
User o = (User) user.newInstance();
o.setName("hello Reflection");
System.out.println(o.getName());
//用有参构造
Class user1 = Class.forName("User");
Constructor declaredConstructor = user1.getDeclaredConstructor(Integer.class, String.class);
User hello_reflection2 = (User)declaredConstructor.newInstance(18, "hello Reflection2");
System.out.println(hello_reflection2.getName());
//通过反射调用普通的方法
Method method = user1.getDeclaredMethod("setName", String.class);
method.invoke(hello_reflection2,"小红");
System.out.println(hello_reflection2.getName());
//通过反射获取private属性
Field name = user1.getDeclaredField("name");
name.setAccessible(true);//关闭安全机制
name.set(hello_reflection2,"小岚");
System.out.println(hello_reflection2.getName());
}
}
获取泛型的信息
-
java的泛型是给编译器javac使用的,确保数据的安全性和免去强制类型转换问题,一旦编译完成就擦除有关泛型的类型
-
反射操作的获取泛型
-
ParameterizedType:参数化类型
-
GenericArrayType:泛型数组
-
TypeVariable:类型变量
-
WildcardType:代表一中种通配符类型表达式
-
import java.lang.reflect.*;
import java.util.ArrayList;
import java.util.Map;
public class Test_fanxing {
//泛型在参数上
public void test1(ArrayList<String> arrayList, Map<String,Integer> map){
}
//泛型在返回值
public ArrayList<Integer> test2(){
return null;
}
//返回值是泛型数组
public ArrayList<String>[] test3(){
return null;
}
public static void main(String[] args) throws NoSuchMethodException, NoSuchFieldException {
Class c1 = Test_fanxing.class;
Method t1 = c1.getMethod("test1", ArrayList.class, Map.class);
//获取方法参数的类型
Type[] types1 = t1.getGenericParameterTypes();
for (Type type : types1) {
System.out.println(type);
}
//获取方法参数里面泛型的类型
types1 = t1.getGenericParameterTypes();
for (Type type : types1) {
if(type instanceof ParameterizedType){
Type[] a1 = ((ParameterizedType) type).getActualTypeArguments();
for (Type type1 : a1) {
System.out.println(type1);
}
}
}
//获取返回值的泛型
Method t2 = c1.getMethod("test2", null);
Type type2 = t2.getGenericReturnType();
System.out.println(type2);
//获取返回值的泛型里面的参数
if(type2 instanceof ParameterizedType){
Type[] types = ((ParameterizedType) type2).getActualTypeArguments();
for (Type type : types) {
System.out.println(type);
}
}
System.out.println("========");
//泛型数组的判断
Method test3 = c1.getMethod("test3", null);
Type genericReturnType = test3.getGenericReturnType();
if(genericReturnType instanceof GenericArrayType){
System.out.println(genericReturnType);
}
}
}
注解与反射
import java.lang.annotation.*;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
//想要获取哪个注解就获取反射的哪个变量、哪个方法,再用getAnnotation(?.class)获取
public class Annotation_Reflection {
public static void main(String[] args) throws NoSuchFieldException {
Class c1 = Student2.class;
//获取类上面的注解
Annotation[] annotations = c1.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation);
}
//获取指定注解的值
myStudent annotation = (myStudent)c1.getAnnotation(myStudent.class);
System.out.println(annotation.value());
//获取注解字段
Field id = c1.getDeclaredField("id");
myField annotation1 = id.getAnnotation(myField.class);
System.out.println(annotation1.columnName());
System.out.println(annotation1.type());
System.out.println(annotation1.length());
}
}