zoukankan      html  css  js  c++  java
  • 2018.8.1 Java中的反射和同步详解

    为何要使用同步?

        java允许多线程并发控制,当多个线程同时操作一个可共享的资源变量时(如数据的增删改查), 
        将会导致数据不准确,相互之间产生冲突,因此加入同步锁以避免在该线程没有完成操作之前,被其他线程的调用, 
        从而保证了该变量的唯一性和准确性。
    

    同步方法和同步代码块的区别

    	同步方法使用synchronize修饰方法,在调用该代码块时,需要获得内置锁(java对象都有一个内置锁,否则就处于阻塞状态)内置锁会保护整个方法。在调用该方法前,需要获得内置锁,否则就处于阻塞状态。
    	2.同步代码块使用synchronized(object){}进行修饰,在调用该代码块时,需要获得内置锁,否则就处于阻塞状态
     代码如: synchronized(object){ 
                //内容
              }
    

    Java 反射机制

    反射的概述Reflection
    	JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
    要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.
    
    	1.字节码。所谓的字节码就是当java虚拟机载入某个类的对象时,首先须要将硬盘中该类的源码编译成class文件的二进制代码(字节码),然后将class文件的字节码载入到内存中,之后再创建该类的对象
    	2.java反射的基础是Class类,Class类实例代表着内中中的一份字节码。
    	3.获取反射的构造函数。有了主要的Class类,要获取类的对象,首先要获取类的构造函数,这里主要使用的是Class类的getConstructor方法	
    

    反射例子

    package fanshe;
    /**
     * 获取Class对象的三种方式
     * 1 Object ——> getClass();
     * 2 任何数据类型(包括基本数据类型)都有一个“静态”的class属性
     * 3 通过Class类的静态方法:forName(String  className)(常用)
     *
     */
    public class Fanshe {
    	public static void main(String[] args) {
    		//第一种方式获取Class对象  
    		Student stu1 = new Student();//这一new 产生一个Student对象,一个Class对象。
    		Class stuClass = stu1.getClass();//获取Class对象
    		System.out.println(stuClass.getName());
    		
    		//第二种方式获取Class对象
    		Class stuClass2 = Student.class;
    		System.out.println(stuClass == stuClass2);//判断第一种方式获取的Class对象和第二种方式获取的是否是同一个
    		
    		//第三种方式获取Class对象 (常用)
    		try {
    			Class stuClass3 = Class.forName("fanshe.Student");//注意此字符串必须是真实路径,就是带包名的类路径,包名.类名
    			System.out.println(stuClass3 == stuClass2);//判断三种方式是否获取的是同一个Class对象
    		} catch (ClassNotFoundException e) {
    			e.printStackTrace();
    		}
    		
    	}
    }
    
    注意:在运行期间,只能有一个Class对象产生
    

    Java 中 Reflection 和 Introspection 区别?

    说起反射,还有一个相似的概念 ‘Introspection’,字面意思是“自省、内省”,它们之间的区别如下:
    
    内省 
         在运行时检查一个对象的类型或者属性
         最常见的例子就是运行时通过 a instanceof A 来判断 a 对象的类型
    反射 
         用来在运行时检查或者修改一个对象信息
         可以用来实现看似不可能的操作,比如访问私有方法,动态创建对象
         可以看到,反射是在内省的基础上,增加了修改的能力。
    

    通过反射获取构造方法并使用

    package fanshe;
     
    public class Student {
    	
    	//---------------构造方法-------------------
    	//(默认的构造方法)
    	Student(String str){
    		System.out.println("(默认)的构造方法 s = " + str);
    	}
    	
    	//无参构造方法
    	public Student(){
    		System.out.println("调用了公有、无参构造方法执行了。。。");
    	}
    	
    	//有一个参数的构造方法
    	public Student(char name){
    		System.out.println("姓名:" + name);
    	}
    	
    	//有多个参数的构造方法
    	public Student(String name ,int age){
    		System.out.println("姓名:"+name+"年龄:"+ age);//这的执行效率有问题,以后解决。
    	}
    	
    	//受保护的构造方法
    	protected Student(boolean n){
    		System.out.println("受保护的构造方法 n = " + n);
    	}
    	
    	//私有构造方法
    	private Student(int age){
    		System.out.println("私有的构造方法   年龄:"+ age);
    	}
     
    }
    
    
    
    测试类
    	package fanshe;
     
    import java.lang.reflect.Constructor;
    /*
      通过Class对象可以获取某个类中的:构造方法、成员变量、成员方法;并访问成员;
      
      1.获取构造方法:
      		1).批量的方法:
      			public Constructor[] getConstructors():所有"公有的"构造方法
                public Constructor[] getDeclaredConstructors():获取所有的构造方法(包括私有、受保护、默认、公有)
         
      		2).获取单个的方法,并调用:
      			public Constructor getConstructor(Class... parameterTypes):获取单个的"公有的"构造方法:
     			public Constructor getDeclaredConstructor(Class... parameterTypes):获取"某个构造方法"可以是私有的,或受保护、默认、公有;
      		
     			Constructor-->newInstance(Object... initargs)
     */
    public class Constructors {
     
    	public static void main(String[] args) throws Exception {
    		//1.加载Class对象
    		Class clazz = Class.forName("fanshe.Student");
    		
    		
    		//2.获取所有公有构造方法
    		System.out.println("**********************所有公有构造方法*********************************");
    		Constructor[] conArray = clazz.getConstructors();
    		for(Constructor c : conArray){
    			System.out.println(c);
    		}
    		
    		
    		System.out.println("************所有的构造方法(包括:私有、受保护、默认、公有)***************");
    		conArray = clazz.getDeclaredConstructors();
    		for(Constructor c : conArray){
    			System.out.println(c);
    		}
    		
    		System.out.println("*****************获取公有、无参的构造方法*******************************");
    		Constructor con = clazz.getConstructor(null);
    		//1>、因为是无参的构造方法所以类型是一个null,不写也可以:这里需要的是一个参数的类型,切记是类型
    		//2>、返回的是描述这个无参构造函数的类对象。
    	
    		System.out.println("con = " + con);
    		//调用构造方法
    		Object obj = con.newInstance();
    	//	System.out.println("obj = " + obj);
    	//	Student stu = (Student)obj;
    		
    		System.out.println("******************获取私有构造方法,并调用*******************************");
    		con = clazz.getDeclaredConstructor(char.class);
    		System.out.println(con);
    		//调用构造方法
    		con.setAccessible(true);//暴力访问(忽略掉访问修饰符)
    		obj = con.newInstance('男');
    	}
    	
    }
    
    

    获取反射的方法。

    public static void main(String[] args) throws Exception {
    		String s1 = "hello";
    		//參数为函数名,函数的參数(可变长)
    		Method m = s1.getClass().getMethod("charAt", int.class);
    		//參数为要调用的对象,以及函数的參数。这里假设第一个參数为null,表示调用的是类的静态方法
    		System.out.println(m.invoke(s1, 1));
    	}
    

  • 相关阅读:
    201771010113 李婷华 《面向对象程序设计(Java)》第十七周总结
    201771010113 李婷华 《面向对象程序设计(Java)》第十六周总结
    201771010113 李婷华 《面向对象程序设计(java)》第十五周总结
    201771010113 李婷华 《面向对象程序设计(java)》
    201771010113 李婷华 《面向对象程序设计(Java)》第十三周总结
    201771030102-常梦娇 实验四 软件项目案例分析
    201771030102-常梦娇 实验三 结对项目—《西北师范大学学生疫情上报系统》项目报告
    201771030102-常梦娇 实验二 个人项目—《西北师范大学学生疫情上报系统》项目报告
    201771030102-常梦娇 实验一 软件工程准备-《构建之法》初识
    201771030115-牛莉梅 实验四 软件项目案例分析
  • 原文地址:https://www.cnblogs.com/qichunlin/p/9398719.html
Copyright © 2011-2022 走看看