码迷,mamicode.com
首页 > 编程语言 > 详细

2018.8.1 Java中的反射和同步详解

时间:2018-08-01 01:01:20      阅读:212      评论:0      收藏:0      [点我收藏+]

标签:object   的区别   源码编译   获取   导致   rac   ati   必须   student   

为何要使用同步?

    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));
    }

2018.8.1 Java中的反射和同步详解

标签:object   的区别   源码编译   获取   导致   rac   ati   必须   student   

原文地址:https://www.cnblogs.com/qichunlin/p/9398719.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!