package com.day14.json;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.*;
import java.util.Properties;
import java.util.Random;
/**
* Author: Json
* Date: 2021/10/6
**/
public class JsonTest {
public static void main(String[] args) {
System.out.println("加油把");
//java 反射机制
}
@Test
public void test1(){
//反射之前 的操作
//1.创建对象
Person person=new Person("JSON",12);
//2. 调用内部属性 方法
person.show();
//在person类的外部不能调用私有的方法或属性
}
@Test
public void test2() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
//反射之后
Class c= Person.class;
// 1.通过反射 创建Person类的对象
Constructor constructor=c.getConstructor(String.class,int.class);
Object object= constructor.newInstance("Json",123);
System.out.println(object.toString());
//强转
Person person =(Person) object;
System.out.println(person.getName());
//2.通过反射 调用对象的指定的方法和属性
//调用更改类里的属性
Field age=c.getDeclaredField("age");
age.set(person,12);
System.out.println(person.toString());
//调用类中方法
Method show=c.getDeclaredMethod("show");
show.invoke(person);
//通过反射是可以调用Person类中的私有结构的
//如果 私有方法 私有构造器 私有属性
//调用私有的构造器
Constructor constructor1= c.getDeclaredConstructor(String.class);
//激活私有方法权限调用 保持当前属性是可访问的
constructor1.setAccessible(true);
Person person1=(Person) constructor1.newInstance("whL");
System.out.println(person1.getName());
//调用修改私有属性
Field name=c.getDeclaredField("name");
name.setAccessible(true);
name.set(person1,"hahah");
System.out.println(person1);
//调用私有方法
Method eat=c.getDeclaredMethod("eat", String.class);
eat.setAccessible(true);
String naa= (String) eat.invoke(person1,"21312321");
System.out.println(naa);
}
// 通过直接new的方式或反射的方式都可以调用公共的结构 开发中用哪个?
//建议 直接new的方式
//什么时候会使用反射的方式? 反射的特征 动态性
//比如 api 接口请求地址 就是利用反射实现的
//根据url来的路径 来new相对应的对象
// 反射机制与面向对象中的封装性是不是矛盾的?如何看待两个技术
// 不矛盾
@Test
public void test3() throws ClassNotFoundException {
//class实例的理解
//调用 class
//方式一
Class<Person> c=Person.class;
//方式二 通过运行时对象 调用
Person person=new Person();
Class person1=person.getClass();
//方式三 通过class 静态方法 获取 class
Class.forName("com.day14.json.Person");
}
//读取配置文件
@Test
public void test4() throws IOException {
//默认在当前module下的配置文件
Properties properties=new Properties();
// FileInputStream fis=new FileInputStream("jdbc.properties");
// properties.load(fis);
//classLoader 类的加载器 可以一层一层找 类的加载器
// 根据加载器的位置 找相对应的配置文件
//默认在src下的配置文件
ClassLoader classLoader=ClassLoaderTest.class.getClassLoader();
InputStream is=classLoader.getResourceAsStream("jdbc1.properties");
properties.load(is);
}
//体验反射的动态性
@Test
public void test5(){
int num=new Random().nextInt(3);
//根据运行 造相对应的类
String classPath;
switch (num){
case 0:
classPath= "java.util.Date";
break;
case 1:
classPath="java.lang.Object";
break;
case 2:
classPath="com.day14.json.Person";
break;
default:
throw new IllegalStateException("Unexpected value: " + num);
}
try {
Object object=new JsonTest().getInstance(classPath);
System.out.println(object);
} catch (Exception e) {
e.printStackTrace();
}
}
public Object getInstance(String classPath) throws Exception {
Class c=Class.forName(classPath);
return c.newInstance();
}
//获取当前运行时类的属性结构
@Test
public void test6(){
Class c= com.day14.json1.Person.class;
//获取属性结构
//只能获取 当前运行时类及其父类中的公共的(Public)属性结构
Field[] fields = c.getFields();
for (Field f:fields){
System.out.println(f);
}
System.out.println("*****************");
//只能获取 当前运行时类属性结构 (不包含父类)
Field[] declaredFields = c.getDeclaredFields();
for (Field f:declaredFields){
System.out.println(f);
}
}
//权限修饰符 数据类型 变量名
@Test
public void test7(){
Class c= com.day14.json1.Person.class;
Field[] declaredFields = c.getDeclaredFields();
for (Field f:declaredFields){
//权限修饰符
System.out.println(f.getModifiers()); //返回int
System.out.println(Modifier.toString(f.getModifiers())); //转成字符串
// 数据类型
System.out.println(f.getType());
//变量名
System.out.println(f.getName());
}
}
//获取运行时类的方法结构
@Test
public void test8(){
Class c= com.day14.json1.Person.class;
//获取当前运行时类及其父类的所有的公共方法
Method[] Methods = c.getMethods();
for (Method m:Methods){
System.out.println(m);
}
System.out.println("******************");
//获取当前运行时类的所有的方法(不包含父类)
Method[] declaredMethods = c.getDeclaredMethods();
for (Method m:declaredMethods){
System.out.println(m);
}
}
//获取运行时类的泛型的父类 和普通父类
@Test
public void test9(){
Class c= com.day14.json1.Person.class;
// 普通父类 c.getSuperclass();
Type genericSuperclass = c.getGenericSuperclass(); //泛型的父类
System.out.println(genericSuperclass);
//获取父类的泛型的类型
ParameterizedType parameterizedType= (ParameterizedType) genericSuperclass;
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
System.out.println(actualTypeArguments[0].getTypeName());
}
//获取运行时类的接口
//用的时候找
//获取运行时类的包
//用的时候找
//获取运行时类的注解
@Test
public void test10(){
//通过反射读取注释内容后 去做一些事情
Class c= com.day14.json1.Person.class;
Annotation[] annotations = c.getAnnotations();
for (Annotation annotation:annotations){
System.out.println(annotation);
}
}
//调用运行时类的指定的结构 属性 方法 构造器
@Test
public void test11() throws NoSuchFieldException, IllegalAccessException, InstantiationException {
//通过反射读取注释内容后 去做一些事情
Class c= com.day14.json1.Person.class;
Field id = c.getField("id");
System.out.println(id);
//声明对象
//Person person = (Person) c.newInstance();
//设置 对象中的 属性的值
// id.set(person,2123);
//获取对象中的 属性的值
// int id1= (int) id.get(person);
// System.out.println(id1);
//如果获取私有的
// Field name = c.getDeclaredField("name");
// //设置属性可访问的权限
// name.setAccessible(true);
// name.set(person,"json");
// name.get(person);
}
}java的反射详解
原创
©著作权归作者所有:来自51CTO博客作者json____的原创作品,请联系作者获取转载授权,否则将追究法律责任
上一篇:java中泛型的详解
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
Java反射详解
Java反射详解
Java开发 Java教程
















