反射_java_大全(学习笔记ing)

一.简介

1.类加载

将class文件读取到内存中的过程,称为类加载

class文件的加载由ClassLoader完成-----类加载器

类加载器三种类型:

* BootStrapClassLoader:启动类加载器,用C++写,主要负责加载%JAVA_HOME%/jre/lib路径下的类

* ExtClassLoader:扩展类加载器,主要负责加载%JAVA_HOME%/jre/lib/ext路径下的类

* AppClassLoader:系统类加载器,主要负责加载classpath路径下的类(对于Eclipse来说,就是项目路径/bin)

* 类名.class.getClassLoader()获取当前类的类加载器

class文件读取内存中会被封装为一个 Class类对象

2.反射

* 对于任意一个类可以获取这个类的属性和方法

* 对于任意一个对象可以调用这个对象的属性和方法

  在运行时动态的获取信息以及调用对象的方法的功能称为反射 - reflection

 3.相关API

反射相关的类或接口都java.lang包

类/接口作用  
Class 表示运行中的类和接口
Field表示类中的属性
Method方法
Constructor构造方法
Package
Modifier 修饰符
Parameter参数
Annotation注解 

二.Class对象

1.简介

运行中的class文件通过Class对象来表示

* Class对象在类加载时由JVM自动创建,一个类对于一个Class对象

* Class类没有公共的构造方法,不能自己创建class对象,但可以获取实例

* Class是反射的核心,要操作类中的属性和方法,必须先获取Class对象

2.获取class对象三种方式

1.  调用对象的getClass()方法
2. 调用对象的class属性
3. 调用Class类中的forName()静态方法

//		getClass()方法
		Card card = new Card();
		Class<? extends Card> class1 = card.getClass();
		System.out.println(class1);
		
//		类名.class
		Class card2=Card.class;
		System.out.println(card2);
		
//		Class.forName("包名+类名")
		Class<?> card3 = Class.forName("ten_first.Card");
		System.out.println(card3);

3.常用方法

Class card=Card.class;
//		获取类中的信息
		System.out.println("全类名:"+card.getName());
		System.out.println("简单类名:"+card.getSimpleName());
		System.out.println("是否为接口:"+card.isInterface());
		
//		获取父类信息 
		Class superclass = card.getSuperclass();
		System.out.println("父类名字:"+superclass.getName());

//		获取接口
		Class[] interfaces = card.getInterfaces();
		for (Class c : interfaces) {
			System.out.println(c+"  ");
		}
		
//		获取修饰符
		int modifiers = card.getModifiers();//以常量代替修饰符
		System.out.println("修饰符:"+Modifier.toString(modifiers));
		
//		获取包
		Package package1 = card.getPackage();
		System.out.println("包:"+package1);
		
//		调用无参构造方法————通过反射的方式创建对象
		Object newInstance;
		try {
			newInstance = card.newInstance();
			System.out.println(newInstance);
		} catch (InstantiationException | IllegalAccessException e) {
			e.printStackTrace();
		}

输出:
全类名:ten_first.Card
简单类名:Card
是否为接口:false
父类名字:ten_first.Paper
interface java.io.Serializable  
interface java.lang.Cloneable  
修饰符:public
包:package ten_first
card [name=null, id=0]

三.反射的操作

模板操作:获取所有+获取指定单个+其他

1.操作Field(属性)

			Class tea=Tea.class;
			
//			1.1获取当前类以及父类中所有public修饰的属性
			Field[] fields = tea.getFields();
//			1.2获取当前类以及父类中所有修饰的属性
			fields =tea.getDeclaredFields();
			
			for (Field field : fields) {
				System.out.println(field.getName()+"	"+field.getType()+"	"+
						Modifier.toString(field.getModifiers())+"\t");
			}
			
//			2获取当前指定的属性
			Field price = tea.getField("price");//public 
			Field num = tea.getDeclaredField("number");//private
			
//			3对于一个实例 用反射为属性赋值	属性.set(对象,值)
			Tea puer = new Tea();
			num.setAccessible(true);//私有需要先取消检查设置 取消修饰的作用
			num.set(puer,12);
			price.set(puer,1.9);
			
//			4属性.get(对象)=值
			Object object = num.get(puer);
			System.out.println(object);
			Object object2 = price.get(puer);
			System.out.println(object2);

2.操作Method(方法)

		Class tea=Tea.class;
		
//		1.获取当前类和父类的方法
		Method[] methods = tea.getMethods();//public
		methods=tea.getDeclaredMethods();//含private
		for (Method m : methods) {
			System.out.println(m.getName()+"\t"+m.getReturnType()+"\t"+
						m.getModifiers()+Arrays.toString(m.getParameters()));
		}
		
//		2.指定获取方法
		Method m1 = tea.getMethod("a");//public 
		Method m2 = tea.getDeclaredMethod("b",int.class);//private
		Method m3 = tea.getMethod("b",int.class,int.class);// (参数名,参数列表)
		
//		3.通过反射调用方法  只能调用public的方法  	除非去除限制
		Tea iron = new Tea();
		m3.setAccessible(true);
		Object invoke = m3.invoke(iron,1,2);
		System.out.println(invoke);//方法的返回值
public void a() {
		
	}
	
	private void b(int x) {
		
	}
	
	public int b(int x,int y) {
		System.out.println("参数1"+x+"参数2"+y);
		return x+y;
	}

3.操作Constructor(构造方法)

		Class tea=Tea.class;
//		1.1获取构造方法 public修饰
		java.lang.reflect.Constructor[] consructor=tea.getConstructors();
//		1.2获取构造方法 所有的 包含private修饰
		consructor= tea.getDeclaredConstructors();
		for (java.lang.reflect.Constructor c: consructor) {
			System.out.println(c);
		}
		
//		2.获取指定的构造方法 仅public/public+private
		java.lang.reflect.Constructor c1 = tea.getConstructor(int.class,int.class);
		java.lang.reflect.Constructor c2 = tea.getDeclaredConstructor(int.class); 
	
//		通过反射调用构造方法 相当于new对象
		c1.setAccessible(true);//此处一个参数的构造方法是private 需要先破除限定
		Object t1 = c1.newInstance("20");
//		直接通过Class对象 调用构造   #常用方法中提及
		Object t2 = tea.newInstance();

四.注解

1.简介

Annotation相当于一种标识,是一种新的类型,与类,接口,枚举同一个层次

语法:@xxx,可以声明在类,属性,方法,参数等前面 

用来表示一些特定的功能

2.JDK自带的注解

@override         | 标记在方法前面,该方法是重写父类的方法

@SuppressWarnings | 关闭警告信息

3.自定义注解

语法:
//元注解
public @interface Test_注解 {
	//抽象方法
}
public @interface MyAnnotation {
	int a();
	String b();
	boolean[] value();
	int e() default 000;
}

@MyAnnotation(a = 0, b = "ddd", value = { false })

元注解:标注在注解上的注解

注解作用 
@Target定义注解的作用域,可以用来标记在那些元素,通过ElementType来取值,不填,默认表示可以声明在任何元素
@Retention定义注解的声明周期 通过枚举@RetentionPolicy来取值
@Documented生成API文档时,包含该注解
@Inherited子类可以继承父类的注解

@Target 的取值: 

* type: 类和接口
* field :属性
*  method 方法
*  PARAMETER 参数
* CONSTRUCTOR 构造

@Retention的取值:

* RUNTIME 注解可以保存在整个程序运行期间
* SOURCE 只放在源文件中,不参与编译,class文件没有
* CLASS  参与编译,但类加载时不能加载,程序运行时没有

4.使用自定义注解

语法: @注解名(属性名=属性值,属性名= 属性值)
在使用注解时需要为注解中的抽象方法指定返回值,称为:为注解指定属性值
属性名就是注解类中的方法名
 
1.返回数组c={a,b,c} 如果数组中仅一个元素 可省略大括号
2.注解中可以写抽象方法 必须无参无异常 使用时需要传入返回值(all)
3.注解中 void d();错误的     必须要有返回值
4.使用时:不需要赋值时@MyAnnotation        省略()
5.String e() default "eee"    使用default为方法指定返回值 使用注解时 不需要传入值
6.int value();  仅方法名为value 使用-传入参数值时:可省略属性名=结构 @MyAnnotation(555)

5.注解上的反射

		Class user=User.class;
		
//		1.获取类上的注解
		Annotation[] a1 = user.getAnnotations();
//		没有显示由于@Rentenion(RentenionPolicy.SOURCE) 没有class文件
		for (Annotation a : a1) {
			System.out.println(a);
		}
		
		Annotation myannotation = user.getAnnotation(MyAnnotation.class);
		System.out.println(myannotation);
		
//		2.获取属性上的注解
		Field field = user.getDeclaredField("age");
		Annotation[] a2 = field.getAnnotations();
		
//		3.获取方法上的注解
		Method method = user.getMethod("way");
		MyAnnotation a3 = method.getAnnotation(MyAnnotation.class);
		
//		4.通过反射获取注解的属性值 用注解对象.方法名
		System.out.println(a3.value());
		System.out.println(a3.e());//赋默认值

这是一边看视频一边学习的笔记-借用了部分老师的笔记内容-如有侵权,通知删除!

新手小白学习之路~~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值