精华内容
下载资源
问答
  • java反射机制详解
    2020-12-14 16:27:05

    https://blog.csdn.net/wei_zhi/article/details/52730249

    更多相关内容
  • Java反射机制详解

    2020-09-03 01:54:51
    主要介绍了Java反射机制,首先简单介绍了反射机制的预备知识,进一步分析了Java反射机制的原理、实现技巧与应用方法,需要的朋友可以参考下
  • java反射机制详解

    2017-05-11 20:10:41
    java反射机制的详细描述
  • 主要介绍了Java 反射机制详解及实例的相关资料,需要的朋友可以参考下
  • JAVA反射机制详解视频

    2018-12-30 15:05:21
    (通过反射获取无参构造方法并使用) (通过反射获取带参构造方法并使用) (通过反射获取私有构造方法并使用) (通过反射获取成员变量并使用) (通过反射获取无参无返回值成员方法并使用) (通过反射获取带参带返回值成员...
  • JAVA反射机制详解

    2021-04-09 14:59:52
    (1)Java反射机制的核心是在程序运行时动态加载类并获取类的详细信息,从而操作类或对象的属性和方法。本质是JVM得到class对象之后,再通过class对象进行反编译,从而获取对象的各种信息。 (2)Java属于先编译再...

    一、什么是java的反射机制:

    (1)Java反射机制的核心是在程序运行时动态加载类并获取类的详细信息,从而操作类或对象的属性和方法。本质是JVM得到class对象之后,再通过class对象进行反编译,从而获取对象的各种信息。

    (2)Java属于先编译再运行的语言,程序中对象的类型在编译期就确定下来了,而当程序在运行时可能需要动态加载某些类,这些类因为之前用不到,所以没有被加载到JVM。通过反射,可以在运行时动态地创建对象并调用其属性,不需要提前在编译期知道运行的对象是谁。

    (3)Java的反射机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键

    **

    二、java的反射机制的原理

    (1)首先明确的概念: 一切皆对象----类也是对象.

    (2)然后知道类中的内容 :modifier constructor field method.

    (3)其次明白加载: 当Animal.class在硬盘中时,是一个文件,当载入到内存中,可以认为是一个对象,是java.lang.class的对象.

    **

    三、java的反射机制的原理的功能

    (1)在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。

    (2)Java的反射机制就是增加程序的灵活性,避免将程序写死到代码里。 例如: 实例化一个 person()对象, 不使用反射,需要new person(); 如果想变成实例化其他类,那么必须修改源代码,并重新编译…

    展开全文
  • 本文主要介绍Java 反射机制的知识,这里提供示例代码帮助大家学习理解此部分知识,有需要的小伙伴可以参考下
  • 主要介绍了java 反射机制详解及实例代码的相关资料,需要的朋友可以参考下
  • 主要为大家详细介绍了Java反射机制的相关资料,主要包括反射的概念、作用
  • java反射机制详解与应用.pdf
  • java 反射机制详解

    2008-12-17 09:56:54
    比较详细讲述了java反射机制,收获颇丰。希望大家能够共同学习,一起进步。
  • java反射机制详解及Method.invoke解释.pdf
  • Java 反射机制详解

    2021-03-16 12:21:29
    引言本文主要介绍Java中,有关反射机制、类的加载过程、以及控制反转方面的内容。Java 反射机制Java创建对象的方式有哪些:new、反射、反序列化、克隆class对象获取的方法有哪些:类名.class、getClass、forName、...

    引言

    本文主要介绍Java中,有关反射机制、类的加载过程、以及控制反转方面的内容。

    Java 反射机制

    Java创建对象的方式有哪些:new、反射、反序列化、克隆

    class对象获取的方法有哪些:类名.class、getClass、forName、classLoader.loadClass(‘包类名全路径’)---> 区别在于有没有初始化步骤(statis)

    类的加载顺序

    Class装载过程:加载、链接(验证、准备、解析)、初始化

    Class初始化的详细步骤:

    如果这个类还没有被加载和链接,那就先进行加载和链接

    如果这个类存在父类,并且父类还没有初始化,那就先初始化直接父类

    如果类型存在初始化语句,一次执行初始化语句

    Class初始化6大时机:

    创建类的实例(new、class.newInstance、constructor.newInstance)

    访问类中的某个静态变量,或者对静态变量进行赋值

    调用类的静态方法

    Class.forName

    完成子类的初始化

    程序的引导入口

    JDBC编程为什么用Class.forName类进行加载驱动?--> 通过classforName 进行初始化statis、注册Driver

    Java反射

    优点:增加代码的灵活度、可读性更强;

    缺点:(在量大的情况下)相比较于直接调用性能会下降、封装性不好(会暴露内部安全)

    反射慢的原因:寻找class字节码的过程、判断安全机制

    Java反射中,如果需要对私有的属性进行访问,需要设置强制访问(setAccessible)。

    class.newInstance()的本质是什么?--> 该方案会首先找指定class中默认的无参数的构造函数(如果该class已经设定了一个新的有参数的抛出异常)

    Java控制反转(Spring IOC和DI)

    IOC(控制反转),把创建对象的控制权交给程序(容器):构造器、静态工厂、实例方法

    DI(依赖注入),对象创建过程中,容器动态构建所需的对象:构造器、setter函数

    展开全文
  • 主要介绍了Java 反射机制实例详解的相关资料,这里对java反射机制进行了详细的分析,需要的朋友可以参考下
  • 详细解析java反射机制
  • Java-反射机制详解

    千次阅读 2022-04-12 20:56:08
    2 通过反射机制反编译一个类的属性,方法,构造方法。 3 通过反射机制访问一个类的【属性】,调用一个类的【方法】及【构造方法】。 4 注释反射 5 通过I/O流读取users1info文件来获取字符串类名进行反射操作 6 利用...

    1  定义: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法,这种动态获取、调用对象方法的功能称为java语言的反射机制。

     2  作用: 反射机制可以操作字节码文件,也就是说通过反射我们可以获取构造器,对象,属性,方法(原本不知道)

    一,  获取class的三种方式

        (1)   通过该类的对象去获取到对应的Class对象

    Class string_class01 = " ".getClass();

        这种方法基本不用,这里显然和反射机制相悖(已有类对象 了还去用反射获取Class类对象干嘛,多此一举)

        (2) 通过全限定名来获取Class对象

    Class string_class02 = Class.forName("java.lang.String");

       (3)  通过类名.class

       最好用,也更安全!

    Class string_class03 = String.class;
    public class test06 {
    
    	public static void main(String[] args) throws ClassNotFoundException {
    		Class string_class01 = " ".getClass();
    		Class string_class02 = Class.forName("java.lang.String");
    		Class string_class03 = String.class;
    		System.out.println(string_class01);
    		System.out.println(string_class02);
    		System.out.println(string_class03);
    	}
    
    }
    //结果
    //class java.lang.String
    //class java.lang.String
    //class java.lang.String

    二,类Field,Method ,Constructor

       通过反射机制反编译一个类的属性,方法,构造方法。

    public class test05 {
    	public static void main(String[] args) throws Exception {		
    		Class user02 = Class.forName("fans.users1");
    		StringBuilder str = new StringBuilder();
    		str.append(Modifier.toString(user02.getModifiers())+" class "+user02.getSimpleName()+"{\n");	
    		//通过Field类反射获取类users1属性
    		Field[] field = user02.getDeclaredFields();
    		for(Field f:field) {
    			str.append("\t"+Modifier.toString(f.getModifiers())
    			               +" "+f.getType().getSimpleName()
    			               +" "+f.getName()+" \n");
    		}	
    		//通过Constructor类反射获取类users1构造方法
    		Constructor[] con = user02.getConstructors();
    		str.append("\n");
    		for(Constructor c :con) {
    			str.append("\t"+Modifier.toString(c.getModifiers())+" "
    					   +user02.getSimpleName()+"(");
    			Class[] pp = c.getParameterTypes();
    			for(Class cc:pp) {
    				str.append(cc.getSimpleName()+",");
    			}
    			if(pp.length>0) {
    				str.deleteCharAt(str.length()-1);
    			}
    			str.append("){}\n");
    		}			
    		//通过Method类反射获取类users1方法
    		Method[] method = user02.getDeclaredMethods();
    		str.append("\n");
    		for(Method m:method) {
    			str.append("\t"+Modifier.toString(m.getModifiers())+" "
    		                                 +m.getReturnType().getSimpleName()+" "
    					                     +m.getName());
    			str.append("( ");
    			Class[] p = m.getParameterTypes();
    			for(Class p01:p) {
    				str.append(p01.getSimpleName()+",");
    			}
    			str.deleteCharAt(str.length()-1);
    			str.append("){}\n");
    		}
    		str.append("}");
    		System.out.println(str);
    		
    	}
    
    }
    

     通过反射机制访问一个类的【属性】,调用一个类的【方法】及【构造方法】。

    public class test06 {
    	public static void main(String[] args) throws Exception {
            
    //通过new调用users1的方法
    		users1 u01= new users1();
    		if( u01.login("admin", "Admin@123")) 
    			System.out.println("登入成功!");
    		else 
    			System.out.println("用户名或密码错误!");	
    		System.out.println("------------------------");
    //通过反射调用users1的方法
    		// 获取类的class
    		Class u02class = users1.class;
    		//创建对象
    		Object u0201 = u02class.newInstance();//该操作会默认调用无参构造
    		//获取method
    		Method loginmethod = u02class.getDeclaredMethod("login", String.class,String.class);
    		//获取loginmethod的invoke方法的返回值
    		Object retValue = loginmethod.invoke(u0201, "admin","Admin@123");
    		System.out.println(retValue);
    		boolean retlogin = (boolean) retValue;
    		System.out.println(retlogin?"登入成功!":"登入失败!");
    		
    		Method loninmethod01 = u02class.getDeclaredMethod("login", String.class);
    		boolean retlogin01 = (boolean) loninmethod01.invoke(u0201, "admin");
    		System.out.println(retlogin01?"登入成功!":"登入失败!");
    	    
    	    //调用无参方法
    		u02class.getDeclaredMethod("logout").invoke(u0201);
    		System.out.println("------------------------");
    //通过new调用users1的构造方法	
    		users1 u02 = new users1();
    		users1 u03 = new users1("张三");
    		users1 u04 = new users1(true, "李四");
    		System.out.println("------------------------");
    //通过反射调用users1的构造方法	
    		//创建class
    		Class u03class = Class.forName("fans.users1");
    		Object u0301 = u03class.newInstance();
    		
    		Constructor cons = u03class.getConstructor();
    		cons.newInstance();
    		Constructor cons01 = u03class.getConstructor(String.class);
    		cons01.newInstance("张三");
    		Constructor cons02 = u03class.getConstructor(boolean.class,String.class);
    		cons02.newInstance(true,"李四");
    		Constructor cons03 = u03class.getConstructor(int.class,String.class);
    		Object retcons03 = cons03.newInstance(22,"赖滢");
    		System.out.println(retcons03);
    		System.out.println("------------------------");
    //通过new访问users1的属性
    		users1 u05 = new users1();
    		u05.name = "张三";
    		u05.age = 20;
    		u05.sex = true;
    		System.out.println(u05);
    		System.out.println("------------------------");
    //通过反射访问users1的属性
    		Field ff = u03class.getDeclaredField("name");
    		ff.set(u0301, "张三");
    		System.out.println(ff.get(u0301));
    		Field ff01 = u03class.getDeclaredField("ID");
    		ff01.setAccessible(true);//访问私有属性时需打破封装但会破坏其安全性
    		ff01.set(u0301, 303);
    		System.out.println(ff01.get(u0301));
    //获取父类和父接口		
    		System.out.println("------------------获取父类和父接口---------------------");
    		Class strclass = String.class;
            Class strsupclass = strclass.getSuperclass();
            System.out.println(strsupclass.getName());
            
            Class[] strinter = strclass.getInterfaces();
            for(Class c : strinter) {
            	System.out.println(c.getName());
            }	
    	}
    }
    

    上面案例用到users1类

    public class users1 {
    	private int ID;
    	protected int age;
    	boolean sex;
    	public String name;
    	public static final double MATH_PI = 3.1415926;	
        public users1() {
    		super();
    		System.out.println("这是无参构造!");
    	}    
    	public users1(String name) {
    		super();
    		this.name = name;
    		System.out.println(this.name);
    	}
    	public users1(boolean sex, String name) {
    		super();
    		this.sex = sex;
    		this.name = name;
    		System.out.println(this.sex+"="+this.name);
    	}
    	public users1(int age, String name) {
    		super();
    		this.age = age;
    		this.name = name;
    	}
    	@Override
    	public String toString() {
    		return "users1 [ID=" + ID + ", age=" + age + ", sex=" + sex + ", name=" + name + "]";
    	}
    	/**
         * 
         * @param name  账户
         * @param password 密码
         * @return
         */
        public static boolean login(String name,String password) {
        	if("admin".equals(name)&&"Admin@123".equals(password)) 
        		return true;
        	return false;
        }
        public void logout() {
        	System.out.println("账户已安全退出!");
        }
        public boolean login(String name) {
        	return "admin".equals(name)? true:false;
        }
    }
    

    三、反射API 

    getModifiers(),获取字段和方法等的修饰符类型,返回值是int类型,什么都不加是0,public 是1,private是2,protected是4,static 是8,final是16,等等,多个修饰符修饰的话,返回的是每个修饰符代表的int值的和 

    、、、、、、、、可自行查API文档

    API文档https://www.runoob.com/manual/jdk1.6/java.base/java/lang/Class.html

    四, 注释反射 

    1 先创建一个名叫ID的注释

      若还不会创建和理解的请看Java-注释详解

    @Documented
    @Retention(RUNTIME)
    @Target({ TYPE, FIELD, METHOD })
    public @interface ID {
    	int id() default 205;
    	String name();
    	mark chengji();
    }

    2 创建mark(代表成绩且该处用枚举实现)

      若不知如何创建或不是很理解就评论 收藏关注后期就出相应教程!

    public enum mark {
    	不及格,及格,良,优;
    }
    

    3 创建users类并在相应的位置标识注释

    @ID(name = "zwy", chengji=mark.不及格)
    public class users {
    	@ID(name = "zwy", chengji = mark.优)
    	private int ID;
    	protected int age;
    	boolean sex;
    	public String name;
    	public static final double MATH_PI = 3.1415926;
    }

    4 创建被ID注释的类没有有int型的id的异常类

     若不知如何创建或不是很理解就评论 收藏关注后期就出相应教程!

    public class NotIdException extends RuntimeException{
    	public NotIdException() {
    		
    	}
       public NotIdException(String s) {
    		super(s);
    	}
    	
    }
    

    5 创建测试类test01并实现当被ID注释的类必须有int型的id 属性否则抛出异常!

    public class test01 {
    	public static void main(String[] args) throws NoSuchFieldException, SecurityException {
    		Class userclass = users.class;
    		Field ff = userclass.getDeclaredField("ID");
    		//判断userclass的ID属性是否被注释
    		System.out.println(ff.isAnnotationPresent(ID.class));
    		//获取属性的注释属性值
          	ID   id	= ff.getAnnotation(ID.class);
          	System.out.println(id.id());
          	System.out.println(id.name());
          	System.out.println(id.chengji());
          	//判断userclass类是否被注释
    		System.out.println(userclass.isAnnotationPresent(ID.class));
    		//获取类的注释属性值
    		ID idclass = (ID) userclass.getAnnotation(ID.class) ;
    		System.out.println(idclass.chengji());
    		//被ID注释的类必须有int型的id 属性否则抛出异常!
    		boolean isid = false;
    			if(userclass.isAnnotationPresent(ID.class)) {
    				Field[] field = userclass.getDeclaredFields();
    				for(Field f:field) {
    					if("ID".equals(f.getName())&& "int".equals(f.getType().getSimpleName())) {
    						isid = true;
    						break;
    					}	
    			}
    				if(!isid) {
    					throw new NotIdException("被ID注释的类必须有int型的id 属性");
    				}
    		}
    	}
    }
    

     五, 可变长度参数

    1 长度个数:0~n
    2 可变 长度参数必须在参数列表最后一个位置上,而且可变长度参数只能有一个
    3 可将可变长度参数看作一个数组
    public class test04 {
    	public static void main(String[] args) {
    		m();
    		m(1,2);
    		m(1,2,3);
    		m2(1,"abc");
    		m2(1,"abc","dc");
    		m3(" ","abc","de","f");
    		String[] strs = {"www",".baidu.","com","//"};
    		m3(strs);
    		m3(new String[]{"我","是","中","国","人"});
    	}
    	public static void m(int... args) {
    		System.out.println("m方法执行");
    	}
    	/*
    	 * public static void m1(int... args1 ,String... args2) { }//报错!只要一个且在最后!
    	 */
    	public static void m2(int a,String...args) {
    		System.out.println("m2方法执行");
    	}
    	public static void m3(String...args) {
    		//args有length说明是一个数组
    		for(int i=0;i<args.length;i++) {
    			System.out.print(args[i]+" ");
    		}
    	}
    }
    

    六, 扩展 

    1 通过I/O流读取users1info文件来获取字符串类名进行反射操作

    //通过I/O流读取userinfo文件
    		FileReader reader = new FileReader("userinfo1");
    		File f = new File("userinfo1");
    		//创建属性类对象
    		Properties p = new Properties();
    		//加载
    		p.load(reader);
    		//关闭流
    		reader.close();
    		Class s3 = Class.forName(p.getProperty("students"));
    		System.out.println(s3);
    		

    2 获取userinfo文件的绝对路径(增强代码的健壮性)

    String path = Thread.currentThread().getContextClassLoader().getResource("fans/userinfo2").getPath();
    InputStream reader = Thread.currentThread().getContextClassLoader().getResourceAsStream("fans/userinfo2");

    3 若获取的绝对路径有中文乱码进行解码

    URLDecoder.decode(path,"UTF-8")
    String path = Thread.currentThread().getContextClassLoader().getResource("fans/userinfo2").toURI().getPath();

    4 使用绝对路径进行获取字符串类名

    InputStream reader = Thread.currentThread().getContextClassLoader().getResourceAsStream("fans/userinfo2");
    		FileReader fr01 = new FileReader(path);
    		Properties p01 = new Properties();
    		p01.load(reader);
    		reader.close();
    		Class c01 = Class.forName(p01.getProperty("students"));
    		System.out.println(c01);

    5 利用Java自带的资源绑定器获取字符串类名

    ResourceBundle b = ResourceBundle.getBundle("fans/userinfo2");资源绑定器
    System.out.println(b.getString("students"));

    6 在fans包下的txt文件userinfo2

    students=fans.students

    7  public private protected 的简单区别

    //public private protected 的简单区别
    1、public:public表明该数据成员、成员函数是对所有用户开放的,所有用户都可以直接进行调用
    2、private:private表示私有,私有的意思就是除了class自己之外,任何人都不可以直接使用。
    3、protected:protected对于子女、朋友来说,就是public的,可以自由使用,没有任何限制,而对于其他的外部class,protected就变成private。

    在这里插入图片描述

    8  通过反射机制访问一个Java对象的属性,并给属性赋值(set)及获取属性值(get)

    public class test03 extends users {
    	public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException  {	
    		students stu01 = new students();
    		users user01 = new users();
    		Class usersClass = Class.forName("fans.users");
    		//通过new,普通访问一个对象的属性
    		//赋值
    		stu01.no=111;
    		//获取
    		System.out.println(stu01.no);
    		//使用反射机制,创建对象
    		Object obj = usersClass.newInstance();//会自动调用无参构造
    		//获取no属性
    		Field nofield = usersClass.getDeclaredField("no");
    		//给obj对象no属性赋值
    		nofield.set(obj, 222);
    		System.out.println(nofield.getName()+"="+nofield.get(obj));
    		//访问私有属性需要打破封装(打破封装会带来安全问题)才能访问赋值获取
    		Field idfield = usersClass.getDeclaredField("ID");
    		idfield.setAccessible(true);//打破封装
    		idfield.set(obj, 306);
    		System.out.println(idfield.getName()+"="+idfield.get(obj));
    		
    		Field agefisld = usersClass.getDeclaredField("age");
    		agefisld.set(obj, 18);
    		System.out.println(agefisld.getName()+"="+ agefisld.get(obj));
    		
    		//正常new的对象不能访问私有属性,要访问须继承对象类并获取set(),get()方法
    		//user01.ID;//报错访问不了
    		//去users类下获取获取set(),get()方法,通过调用方法进行赋值和取值
    		user01.setID(207);
    		System.out.println("user01ID="+ user01.getID());
    			
    	}
    }
    

    9   只要类加载静态代码快就会执行(所以若只执行类中的静态代码快可以使用反射机制进   行加载)

    public class test02 {
    	public static void main(String[] args) throws ClassNotFoundException, IOException, URISyntaxException {
    		//students s = new students();
            Class c = Class.forName("fans.students");
    	}
    }
    class students {
    	int no;
    	private int ID;
    	public students() {
    		System.out.println("这是个无参构造方法!");
    	}
        static {
        	System.out.println("这里是静态代码块");
        }	
    }
     

    //该通过new对象进行实例化加载会运行整代码块
    //运行结果:

    //通过反射进行类加载只会运行静态类加载块 

     10  获取Class之后,可以调用无参数构造方法来实例化对象

    //通过反射获取class ,通过class实例化对象
    		Class s = Class.forName("fans.students");
    		Object s1  = s.newInstance();//已过时,该方法会默认调用无参构造方法,所以必须保证无参构造存在。
    		//通过new实例化对象
    		students s2 = new students();

     11 Java的getCanonicalName和getName ,getSimpleName()

    Java的getCanonicalName和getName ,getSimpleName()https://blog.csdn.net/hustzw07/article/details/71108945

    展开全文
  • 主要介绍了Java 反射机制的实例详解的相关资料,希望通过本文能帮助到大家,让大家理解掌握反射机制,需要的朋友可以参考下

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 21,550
精华内容 8,620
关键字:

java反射机制详解