JavaSE复习总结(五)(转)

IO流

IO
源结点---------通道-------->目标结点(数据传输的三要素)
用于处理节点之间的数据传输。
源节点---------程序---------目标节点
输入,输出流是相对而言。当源节点向程序传输数据时,对于程序而言,这是输入流,对于源节点来说,这是输出流。
  • 1
  • 2
  • 3
  • 4
  • 5
处理IO的步骤 :
    1) 打开流通道
    2) 通过流通道处理数据
    3) 关闭流通道

写一个流程序的简单步骤:
    1.声明输入/输出流引用,并赋值为null
    2.try-catch-finally在finally中进行关流操作,处理好异常
    3.在try语句块中,创建输入/输出流对象,开始处理文件(先处理,设置判断循环,循环内,先处理已经拿到的,再处理剩下的)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
IO流的重点:常用流,常用方法

        字节流     字符流(编码)
输入      InputStream Reader
输出      OutputStream    Writer

流的分类
    1) 节点流(文件为节点,低级流)
        按照字符处理文件,完成对一些文本文件的复制。
        FileReader 文本文件输入流
            int read(); // 从输入流中读一个字符, 用非法数据-1表示流结束.
            int read(char[] buf); // 从流中读一些字符, 读入到数组中, 返回值就是实际读了多少个字符   
        FileWriter 文本文件输出流
            void write(int ch); // 把参数中的字符写入输出流中
            void write(char[] buf); // 把参数中的字符数组中的全部字符写入输出流中
            void write(char[] buf, int offset, int count); // 把参数中的字符数组的一部分写入输出流
            void flush(); // 把数据刷入硬盘
        按照字节处理文件,完成一些文本文件/音频/视频等二进制存储文件的复制。
        FileInputStream
            int read(); // 从流中读一个字节0~255 用-1表示非法数据
            int read(byte[] buf); // 从流中读一些字节, 返回值就是实际读到的字节数
        FileOutputStream
            void write(int by); 
            void write(byte[] buf);
            void write(byte[] buf, int offset, int count);
    2) 处理流 : 把节点流或其他流包装起来, 用以获取更强大的处理能力
        缓冲流 :内部自带缓冲区, 可以提高效率
            BufferedReader
                String readLine();
            BufferedWriter
                void write(String line)
                void newLine()
            BufferedInputStream 
            BufferedOutputStream
        对象流 : 只处理字节流--->关键用途,对象的序列化,反序列化(这里的对象有自定义对象,数组对象,集合对象等等)
        实现对象的远程传输
            ObjectOutputStream
                void writeXxx(xxx value); // Xxx代表的是8种基本数据类型 writeInt,writeFloat,writeBoolean
                //writeInt(n); // write(n >>> 24); write(n >> 16 & 0x000000FF); write(n >> 8 & 0x000000FF); write(n & 0x000000FF)
                void writeUTF(String str); // 把字符串按照UTF8方式进行编码, 编码 : 把字符串变成字节数组的过程          
            ObjectInputStream   
                xxx readXxx(); // 从流中把8种基本数据类型读出来               
                String readUTF(); // 把流中的字节数组以UTF8编码方式解码成字符串
        转换流 : 只能把字节流转成字符流--->可以根据自己需要自定义编码,自定义编码,编码方式必须和解码方式一致,否则乱码
        处理非本地编码的文件。(默认情况为本地编码)
            InputStreamReader
            OutputStreamWriter

        打印流 : 打印流本身还是字节流
            PrintStream
            PrintWriter
        数据流 : 将对基本数据类型的处理细化
            DataInputStream
            DataOutputStream
对于输入输出流程序参考博客----->IO流总结的非常全面       
随机访问(文件)
    RandomAccessFile.  文件指针.(其中有一个文件指针,对象创建好后,指针指向0号位)
        long getFilePointer(); // 获取文件当前指针
        void seek(long pos); //将指针定位到某一位置
        read();          //每次读一个字节,指针向后移一位
        read(byte[] buf)        
        readXxx()
        readUTF()

        write(int by);    //每次写一个字节,指针向后移一位
        write(byte[] buf)
        writeXxx(xxx value);
        writerUTF(String str)   
随机访问:来个程序
/**
 * 随机访问文件
 */
import java.io.RandomAccessFile;

public class RandomTest {
    public static void main(String[] args) {
        //声明一个随机存取文件的引用并赋值为null
        RandomAccessFile raf = null;
        try {
            //创建对象,给名字,第二个参数是表示文件的特性(可读/可写/同步)
            //对象创建好后,记录指针在0号位
            raf = new RandomAccessFile("随机存取文件", "rw");
            for(int i = 0; i < 26; i++) {
                //write每次写一个字节,每写一个字节指针往后移动一位
                raf.write('a' + i);
            }
            //获取指针的位置
            System.out.println(raf.getFilePointer());
            //将指针定位到指定位置
            raf.seek(0);
            System.out.println(raf.getFilePointer());
            for(int i = 0; i < 10; i++) {
                //每写一个字节,指针向后移动一位
                raf.write('A' + i);
            }
            System.out.println(raf.getFilePointer());
            raf.seek(16);
            for(int i = 0; i < 10; i++) {
                raf.write('0' + i);
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                raf.close();
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
    }
}
工具类 : File 可以代表具体的文件或目录
    long length()       
    long lastModified()
    boolean exists()
    boolean createNewFile()
    String getName()
    String getAbsolutePath()
    boolean mkdir(); 
    boolean mkdirs();// 可以创建多层目录(aa/bb/cc/dd/ee)
    String[] list();    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
文件处给一个程序,来测试下主要方法。  
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;

/**
 * 文件和流
 *
 */
public class FileTest {
    public static void main(String[] args) {
        //声明字符输出流引用变量,并赋值为null
        FileWriter fw = null;
        //声明带有缓冲区的字符输出流引用变量,并赋值为null(较高级)
        BufferedWriter bfw = null;
        //声明一个文件类型的引用,并创建File对象,并将参数("xxx")作为抽象的路径名
        File file = new File("xxx");
        //使用抽象的路径名("xxx")作为名字创建一个目录
        file.mkdir();
        //声明一个文件类型的引用,并创建File对象,并将参数(".")作为抽象的路径名 ---(.代表当前路径)
        File currentFile = new File(".");
        try {
            //创建FileWriter对象,其中参数为文件的名字
            //fw = new FileWriter(new File("xxx/file.info"));
            fw = new FileWriter("xxx/file.info");
            //创建较高级流的对象,参数为低级流对象的引用
            bfw = new BufferedWriter(fw);
            //获取该抽象路径下的所有文件(包括文本文件和目录),并保存在files数组中
            File[] files = currentFile.listFiles();
            //遍历这个数组并将每个元素写入指定文件
            for (int i = 0; i < files.length; i++) {
                //获取文件的名字和长度
                bfw.write(files[i].getName() + "," +  files[i].length());
                //写空行
                bfw.newLine();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //关流操作
            try {
                //只需要关闭高级流就好
                bfw.close();
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
    }
}

线程

多线程 : 
    Thread 类的对象代表一个线程, 可以直接被CPU执行.
进程 : 由多个线程构成.
创建线程的两种方式 :
    1) 实现接口
        1) 写一个具体类, 实现Runnable接口, 并且实现接口中的run方法, 这个run()方法相当于线程的入口
        2) 创建具体类的对象,构造器中以它为实参, 被关联于Thread对象中, Thread对象就是线程对象, 创建标志着栈的建立     
        3) 调用Thread类对象的start()方法, 激活栈, 把Thread的run()方法压入栈底.
        (常用实现接口的方式,一个具体类对象可以创建多个线程,只是这些线程执行的行为(干的活)一致)

    2) 继承类
        1) 写一个具体类, 继承自Thread类, 因为Thread类实现了Runnable接口,在具体类中重写父类的run()方法, 是真的入口方法
        2) 创建具体类对象, 相当于创建了Thread对象
        3) 调用Thread对象的start()方法, 激活栈, 把子类中的run()方法压入栈底.
  •  
  •  
线程重要思想:
    线程做什么事,需要创建几个线程对象,若是线程做的事情一致,只需要一个线程类就行,对于这件事需要几个线程来做,只需要
创建几个线程对象。若是线程做的事情不一致,需要创建多个线程类。
    几个线程做同一件事,若是共享的东西需要同步,就需要用synchronized(锁对象,不同的线程必须是同一把锁对象){需要同步的事务(在一个线程执行这段代码时,不希望其他
    线程对共享资源进行修改)}   
    当需要一个线程在完成任务的时候,叫另外一个线程,执行,就会涉及到线程通信的问题,线程通信必须在同步的基础上,利用锁对象.wait()
锁对象.notify()实现线程的通信。wait()等待并释放拿的锁,notify()随机唤醒等待的线程,notifyall()唤醒所有等待的线程。注意:对于wait,notify的调用一定是锁对象调用
Thread中的方法
    static Thread currentThread(); // 返回执行此方法的栈所属的线程对象
    String getName();
    void setName(String name);
    static void sleep(long millis); // 使执行此方法的栈所属的线程进入睡眠(阻塞) 不抢夺CPU. 不会释放锁..
    void join(); // 使得别的线程在调用本方法后, 进入睡眠, 本线程继续执行完毕后, 别的线程解除阻塞.
    void setDaemon(boolean flag); // 守护线程只用于为用户线程服务, 必须在线程start()方法前设置才管用.
    void interrupt(); // 只能被别的线程调用此方法, 使得本线程结束睡眠, 同时抛出异常
线程的同步安全问题 :
    多个线程同时修改同一个共享资源.

把对共享资源的修改的代码部分加上同步锁.
    synchronized(同步锁对象) {
        代码块; // 具有原子性
    }
线程同步例子:
public class TicketTest {
    public static void main(String[] args) {
        Runnable r = new PrintTicket();
        Thread t = new Thread(r);
        t.setName("窗口1");
        Thread t1 = new Thread(r);
        t1.setName("窗口2");
        t.start();
        t1.start();
    }
}
/*
 *定义一个打印车票的线程类
 *对于线程的创建:
 *线程关键点,先要知道需要线程做的事情,这些线程做的事情相同吗?
 *若相同,一个线程类就好,若是事务不同需要在创建一个新的线程,线程做的事情是放在run中的
 *若是要需要同步,要知道那些代码是共享的,在一个代码进行操作的时候,其余线程不能干涉
 *线程的交互,wait notify 成对使用,一般在开始就唤醒,然后执行完后,wait,并且wait,notify是锁对象调用,
 *若锁对象为"",调用就为,"".notify()唤醒一个线程,"".wait()进入等待,并释放锁,notifyall()唤醒所有线程
 *车票为1000张
 */
class PrintTicket implements Runnable {

    private int ticket = 1;

    @Override
    public void run() {
        while(true) {
            synchronized ("") {
                if(ticket <= 1000) {
                    System.out.println(Thread.currentThread().getName() + ":" + ticket++);
                } else {
                    break;
                }
            }
        }
    }
}
线程通信的例子:
/**
 * 利用两个线程交替打印1~100
 *
 */
public class PrintDataTest2 {
    public static void main(String[] args) {
        Runnable r = new PrintData();
        Thread t = new Thread(r);
        t.setName("线程1");
        Thread t1 = new Thread(r);
        t1.setName("线程2");
        t.start();
        t1.start();
    }
}
/**
 * 定义一个打印数据的线程
 */
class PrintData implements Runnable {

    private int i = 1;
    @Override
    public void run() {
        while(true) {
            synchronized ("") {
                "".notify();
                if(i <= 100) {
                    System.out.println(Thread.currentThread().getName() + ":" + i++);
                } else {
                    break;
                }
                try {
                    "".wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
线程更多例子---->线程

反射

反射---主要涉及众多方法的使用,因此直接进行代码分享。
package com.atguigu.javase.reflect;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;

import org.junit.Test;

public class ReflectTest {
    /**
     * 通过反射获取目标类中的属性
     * 一切皆对象,每个java类具有共性,将共性抽象出来,定义一个是所有类的模板的类(所有的类都是这个类的对象),
     * 这些类都可以依据一个类类模板创建而成,对于这个类模板类,它又将每个类的属性,构造器,方法分别抽象成类与类模板类关联
     */
    @Test
    public void Exer1() {

        String className = "com.atguigu.javase.reflect.Student";
        try {
            //手工加载类模板,并创建类模板对象
            Class clazz = Class.forName(className);
            System.out.println(clazz);
            //获取目标类对象,对象的创建调用目标类的无参构造器
            //利用newInstance()获取目标类的对象
            Object obj = clazz.newInstance();
            //将获取到的对象进行打印
            System.out.println(obj);
            //利用getDeclaredField()方法获取对象属性,所有属性,但是不包括从父类继承的属性
            //getField(属性)获取对象的所有公共属性(包括从父类继承的属性)
            Field nameField = clazz.getDeclaredField("name");
            //setAccessible()突破封装
            nameField.setAccessible(true);
            //对属性进行赋值
            nameField.set(obj, "张三");

            Field ageField = clazz.getDeclaredField("age");
            ageField.setAccessible(true);
            ageField.set(obj, 80);
            System.out.println("-----------------------------");
            System.out.println(obj);
        }
        catch (ClassNotFoundException e) {  //类名不正确
            e.printStackTrace();
        }
        catch (InstantiationException e) {  //构造器调用异常
            e.printStackTrace();
        }
        catch (IllegalAccessException e) {  //构造器封装
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        }
    }
    /**
     * 利用反射获取方法
     */
    @Test
    public void Exer2() {
        String className = "com.atguigu.javase.reflect.Student";
        try {
            //手动加载类模板,并创建类模板对象
            Class clazz = Class.forName(className);
            //利用newInstance获取目标类的对象
            Object obj = clazz.newInstance();
            //getDeclaredMethod(String 方法名, 类型.class 这样写参数列表的类型)
            Method studyMethod = clazz.getDeclaredMethod("study", String.class);
            //突破封装
            studyMethod.setAccessible(true);
            //调用方法
            Object object = studyMethod.invoke(obj, "童话故事");
            System.out.println(object);

        } catch (ClassNotFoundException e) {    //类不存在
            e.printStackTrace();
        } catch (NoSuchMethodException e) {     //方法不存在
            e.printStackTrace();
        } catch (SecurityException e) {         //访问受限
            e.printStackTrace();
        } catch (InstantiationException e) {    //构造器调用错误
            e.printStackTrace();
        } catch (IllegalAccessException e) {    //构造器封装
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    /**
     * Class superClass()方法
     * Class[] getIntefaces()方法
     */
    @Test
    public void Exer3() {
        String className = "com.atguigu.javase.reflect.Student";
        try {
            Class clazz = Class.forName(className);
            //获取父类的类模板对象
            Class superClazz = clazz.getSuperclass();
            System.out.println(superClazz);
            Object obj = superClazz.newInstance();
            Field nameField = superClazz.getDeclaredField("name");
            nameField.setAccessible(true);
            nameField.set(obj, "老王");
            Field ageField = superClazz.getDeclaredField("age");
            ageField.setAccessible(true);
            ageField.set(obj, 65);
            System.out.println(obj);
            Method toStringMethod = superClazz.getDeclaredMethod("toString");
            System.out.println(toStringMethod);
            Class[] interfaces = clazz.getInterfaces();
            for (int i = 0; i < interfaces.length; i++) {
                System.out.println(interfaces[i]);
            }

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取目标类类模板对象的4种方法
     * @throws ClassNotFoundException 
     */
    @Test
    public void Exer4() throws ClassNotFoundException {
        //常用的,利用forName()方法
        //常规使用, 软编码
        String className = "com.atguigu.javase.reflect.Student";
        Class clazz = Class.forName(className);

        //利用类名获取
        //最简单, 硬编码
        Class clazz1 = Student.class;
        System.out.println(clazz == clazz1);

        //通过对象获取
        //比较灵活, 硬编码
        Class clazz2 = new Student().getClass();
        System.out.println(clazz2 == clazz1);

        //可以通过任意一个Class对象获取类加载器
        //通过先获取类加载器,然后手动加载类模板
        //比较复杂, 先获取到类加载器对象,再手工加载类, 软编码
        ClassLoader classLoader = this.getClass().getClassLoader();
        Class clazz3 = classLoader.loadClass("com.atguigu.javase.reflect.Student");
        System.out.println(clazz2 == clazz3);
    }
    /**
     * 类加载器
     */
    @Test
    public void Exer5() {
        ClassLoader AppClassLoader = ClassLoader.getSystemClassLoader();
        System.out.println(AppClassLoader);

        ClassLoader ExtClassLoader = AppClassLoader.getParent();
        System.out.println(ExtClassLoader);

        ClassLoader bootstapClassLoader = ExtClassLoader.getParent();
        System.out.println(bootstapClassLoader);
        System.out.println("--------------------------------------------");
        System.out.println(Object.class.getClassLoader());
        System.out.println(Person.class.getClassLoader());
    }

    /**
     * 利用类加载器读取资源,类加载器读取资源的当前目录是项目目录,src目录
     * 同样可以读取.jar中的文件
     * @throws IOException 
     */
    @Test
    public void Exer6() throws IOException {
        /*
         * 读取自己的配置文件
         */
        /*
        InputStream is = this.getClass().getClassLoader().getResourceAsStream("properities");
        Properties properties = new Properties();
        properties.load(is);
        System.out.println(properties.getProperty("port"));
        */
        InputStream is = this.getClass().getClassLoader().getResourceAsStream("com/sun/corba/se/impl/logging/LogStrings.properties");
        Properties properties = new Properties();
        properties.load(is);
        String  parment = properties.getProperty("IOR.invalidJdk131PatchLevel");
        System.out.println("IOR.invalidJdk131PatchLevel=" + parment);
    }
        //利用反射获取目标类的详细信息
        //提供一个获取目标类细节的公共方法
        public void printClassDetails(String className) throws ClassNotFoundException {
        //获取目标类类模板对象
        Class clazz = Class.forName(className);
        //打印类名,父类
        System.out.print("public class " + clazz.getSimpleName() + " extends " + clazz.getSuperclass().getSimpleName());
        System.out.print(" implements ");
        //打印所有实现的接口
        Class[] allInterface = clazz.getInterfaces();
        for (int i = 0; i < allInterface.length; i++) {
            System.out.print(allInterface[i].getSimpleName() + ",");
        }
        System.out.println("{");
        System.out.println();
        //定义一个Set集合,保存属性(getFields()获取所有的公共属性包括从父类继承的
        getDeclaredFields()获取所有的属性,包括私有,但不包括从父类继承,这两个有交叉利用set集合去重)
        Set<Field> allFields = new HashSet<Field>();
        for (Field field : clazz.getFields()) {
            allFields.add(field);
        }
        for (Field field : clazz.getDeclaredFields()) {
            allFields.add(field);
        }
        //打印所有属性
        Iterator<Field> iterator = allFields.iterator();
        while (iterator.hasNext()) {
            System.out.println("\t" + iterator.next());
        }

        System.out.println();
        //获取所有构造器,并打印
        for (Constructor constructor : clazz.getDeclaredConstructors()) {
            System.out.println("\t" + constructor);
        }
        System.out.println();
        //获取所有方法并用set集合去重,原因和属性一致
        Set<Method> allMethods = new HashSet<Method>();
        for (Method method : clazz.getMethods()) {
            allMethods.add(method);
        }
        for (Method method : clazz.getDeclaredMethods()) {
            allMethods.add(method);
        }
        System.out.println();
        for (Method method : allMethods) {
            System.out.println("\t" + method);
        }
        System.out.println("}");
    }
    //对上边的方法进行测试
    @Test
    public void Exer7() {
        try {
            printClassDetails("java.io.ObjectOutputStream");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //利用反射获取注解
    @Test
    public void Exer8() {
        try {
            Class clazz = Class.forName("com.atguigu.javase.reflect.Teacher");
            Annotation classannotation = clazz.getAnnotation(MyAnn.class);
            System.out.println(classannotation);

            // 可以获取本类所有方法,包括私有方法
            Method concatMethod = clazz.getDeclaredMethod("concat", int.class, double.class, char.class, boolean.class);
            System.out.println("修饰符:" + Modifier.toString(concatMethod.getModifiers()));
            Annotation annotation = concatMethod.getAnnotation(MyAnn.class); // 获取注解
            System.out.println(annotation);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //构造器与反射
    @Test
    public void Exer9() {
        try {
            Class clazz = Class.forName("com.atguigu.javase.reflect.Teacher");
            // 使用其他构造器创建对象
            // 1) 先获取到构造器对象
            //Constructor constructor = clazz.getConstructor(String.class, int.class, double.class);
            Constructor constructor = clazz.getDeclaredConstructor(String.class, int.class, double.class);
            int modifiers = constructor.getModifiers(); // 获取修饰符
            Class[] typesClasses = constructor.getParameterTypes();
            for (int i = 0; i < typesClasses.length; i++) {
                System.out.println("构造器参数:" + typesClasses[i]);
            }
            System.out.println(Modifier.toString(modifiers));
            System.out.println("----------------------------------------------");
            constructor.setAccessible(true);
            // 2) 间接调用构造器完成对象创建
            Object object = constructor.newInstance("立超", 19, 10000);
            System.out.println(object);
            System.out.println("----------------------------------------------");
            /**
             * 单例模式在反射面前什么也不是
             */
            Constructor runtimeConstructor = Runtime.class.getDeclaredConstructor();
            System.out.println(runtimeConstructor);
            runtimeConstructor.setAccessible(true);
            Object object2 = runtimeConstructor.newInstance();
            System.out.println(object2);
            System.out.println(Runtime.getRuntime());

            System.out.println(Object.class.getSuperclass());

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
    //反射与方法toString,hashCode
    @Test
    public void Exer10() {
        try {
            Class clazz = Class.forName("com.atguigu.javase.reflect.Teacher");
            Object object = clazz.newInstance();

            Field nameField = clazz.getDeclaredField("name");
            nameField.setAccessible(true);
            nameField.set(object, "小刚");

            System.out.println(object);

            // 调用方法
            // 1) 从类模板对象中获取方法对象, getMethod会获取本类或者从父类继承的所有公共方式
            Method eatMethod1 = clazz.getMethod("eat", String.class);
            // 2) 通过方法对象间接调用自己
            Object retValue = eatMethod1.invoke(object, "肉包子"); // object.eat("肉包子");
            System.out.println("方法返回值:" + retValue);

            Method eatMethod2 = clazz.getMethod("eat", String.class, int.class);
            eatMethod2.invoke(object, "紫菜包饭", 5);

            Method toStringMethod = clazz.getMethod("toString");
            Object retValue2 = toStringMethod.invoke(object);
            System.out.println("----------------------------");
            System.out.println(retValue2);

            Method hashCodeMethod = clazz.getMethod("hashCode");
            Object retValue3 = hashCodeMethod.invoke(object);
            System.out.println(retValue3);

            // 可以获取本类所有方法,包括私有方法
            Method concatMethod = clazz.getDeclaredMethod("concat", int.class, double.class, char.class, boolean.class);
            concatMethod.setAccessible(true);
            Object retValue4 = concatMethod.invoke(object, 100, 3.14, '你', true);
            System.out.println(retValue4);

            System.out.println("修饰符:" + Modifier.toString(concatMethod.getModifiers()));
            Annotation annotation = concatMethod.getAnnotation(Test.class); // 获取注解
            System.out.println(annotation);

            // getDeclaredMethod, 只能获取本类中声明的方法,从父类继承的无法拿到
            //Method getClassMethod = clazz.getDeclaredMethod("getClass");
            //System.out.println(getClassMethod);

            // 获取父类的私有方法,并通过子类对象来调用, 也是可以成功的, 说明子类继承父类的所有成员!!
            Method method = clazz.getSuperclass().getDeclaredMethod("privateTest");
            method.setAccessible(true);
            method.invoke(object);

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
    //反射与类加载器
    @Test
    public void Exer11() throws IOException {
        // 通类加载器读取的资源文件的当前目录不是项目目录, 而是src目录
        // src目录就是项目的classpath中的
        // 可以直接从jar包中读取资源文件
        //InputStream is = this.getClass().getClassLoader().getResourceAsStream("resource.properties");
        InputStream is = this.getClass().getClassLoader().getResourceAsStream("com/sun/corba/se/impl/logging/LogStrings.properties");
        Properties properties = new Properties();
        properties.load(is);
        System.out.println(properties.getProperty("IOR.nullPoa"));
    }
}
//工具类
import java.io.Serializable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

import org.junit.Test;

@Retention(RetentionPolicy.RUNTIME) // 保持在运行时,才可以通过反射获取
@interface MyAnn {
    String name() default "张三";
    int age() default 30;
}

class Person {

    public String gender;
    public int height;
    public double weight;

    private void privateTest() {
        System.out.println("Person.privateTest()");
    }
}

@MyAnn
public class Teacher extends Person implements Serializable, Comparable {

    private static int counter = 100;

    public static void test() {
        System.out.println("static test()");
    }

    public String name;
    private int age;
    private double salary;

    public Teacher() {
    }

    private Teacher(String name, int age, double salary) {
        super();
        this.name = name;
        this.age = age;
        this.salary = salary;
    }

    public void eat(String something) {
        System.out.println("老师在吃" + something);
    }

    public void eat(String something, int time) {
        System.out.println("老师在吃" + something + "吃了" + time + "小时");
    }

    @MyAnn(name="李四", age=40)
    private static final String concat(int i, double d, char c, boolean b) {
        return "" + i + d + c + b;
    }

    @Override
    public String toString() {
        return "Teacher [name=" + name + ", age=" + age + ", salary=" + salary + "]";
    }

    @Override
    public int compareTo(Object o) {
        return 0;
    }

}
泛型类中反射的使用,使得对象的创建更为灵活。
class Parent<T> {

    T t;
    Class clazz;

    public Parent() {
        Type type = this.getClass().getGenericSuperclass();
        if (!(type instanceof ParameterizedType)) { // 在子类的声明中并没有任何的泛型信息
            clazz = Object.class;
        } else {
            ParameterizedType parameteredType = (ParameterizedType)type;
            Type[] types = parameteredType.getActualTypeArguments();
            clazz = (Class)types[0];
        }
        System.out.println(clazz);
        try {
            t = (T) clazz.newInstance();
            System.out.println(t);
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    public T getT() {
        return t;
    }
}

class Child1 extends Parent<Person> {
}
class Child2 extends Parent {
}
class Child3 extends Parent<PrintStream> {
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值