java反射泛型类型,【Java反射】Java 泛型基础
Java Reflect
綜述
方法的反射
成員變量的反射
構造函數的反射
類加載機制
在面向對象的世界里,萬事萬物皆對象。
但在Java里面有兩樣東西不是對象:靜態的成員、普通數據類型類(但它們有封裝類彌補)
類是對象,類是 java.lang.Class 的實例對象(There is a class named Class)
package com.gcusky.reflect; class ClassDemo{ Foo foo = new Foo(); // Foo的實例對象 /** * foo 是 Foo 類的實例對象 * Foo 是 Class 類的實例對象,又叫類類型(class type) */ // 表示1 -> 任何一個類都有一個隱含的靜態成員變量class Class c1 = Foo.class; // 表示2 -> 已知該類對象可用getClass方法獲取類類型 Class c2 = foo.getClass(); // 表示3 -> 用類的全稱獲取 try { Class c3 = Class.forName("com.gcusky.reflect.Foo"); } catch (ClassNotFoundException e) { e.printStackTrace(); } // 可以通過類的類類型創建該類的實例對象 try { Foo foo1 = (Foo)c1.newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } class Foo
Java 動態加載類
Class.forName("類的全稱")
不僅表示了類的類類型,還代表了動態加載類
編譯時刻加載類是靜態加載類
運行時刻加載類是動態加載類
class Office{ public static void main(String[] args){ // new 創建對象,是靜態加載類,在編譯時就需要加載所有可能使用到的類 if("Word".equals(args[0])) { Word w = new Word(); w.start(); } // Class.forName 創建對象,是動態加載類,在運行時才加載 try { Class c = Class.forName(args[0]) Word w = (Word) c.newInstance(); // 通過類類型,創建該對象 w.start(); } catch (Exception e) { e.printStackTrace(); } } }
Java 獲取方法信息
基本的數據類型,
java.lang.reflect.Method 封裝了關于方法的操作
button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="package com.gcusky.reflect; import java.lang.reflect.Method; public class Demo { /** * 打印類的信息,包括類的成員函數、成員變量 * @param obj 對象 */ public static void printClassMessage(Object obj) { // 要獲取類的信息,首先要獲取類的類類型 Class c = obj.getClass(); // 獲取類的全名 String fullName = c.getName(); /** * Method類:方法對象 * 一個成員方法就是一個Method對象 * getMethods()方法獲取的是所有的public的函數,包括父類繼承而來的 * getDeclaredMethods() 獲取的是所有該類自己聲明的方法,不問訪問權限 */ Method[] ms = c.getMethods(); // c.getDeclaredMethods(); for (int i = 0; i < ms.length; i++) { // 得到方法的返回類型 Class returnType = ms[i].getReturnType(); // 得到方法的名稱 String name = ms[i].getName(); // 獲取參數類型 Class[] paramTypes = ms[i].getParameterTypes(); } } }" title="" data-original-title="復制">
package com.gcusky.reflect; import java.lang.reflect.Method; public class Demo{ /** * 打印類的信息,包括類的成員函數、成員變量 * @param obj 對象 */ public static void printClassMessage(Object obj){ // 要獲取類的信息,首先要獲取類的類類型 Class c = obj.getClass(); // 獲取類的全名 String fullName = c.getName(); /** * Method類:方法對象 * 一個成員方法就是一個Method對象 * getMethods()方法獲取的是所有的public的函數,包括父類繼承而來的 * getDeclaredMethods() 獲取的是所有該類自己聲明的方法,不問訪問權限 */ Method[] ms = c.getMethods(); // c.getDeclaredMethods(); for (int i = 0; i < ms.length; i++) { // 得到方法的返回類型 Class returnType = ms[i].getReturnType(); // 得到方法的名稱 String name = ms[i].getName(); // 獲取參數類型 Class[] paramTypes = ms[i].getParameterTypes(); } } }
Java 獲取成員變量信息
成員變量也是對象
java.lang.reflect.Field 封裝了關于成員變量的操作
button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text=" /** * 成員變量也是對象,Field封裝了關于成員變量的操作 * getFields()獲取的是所有的public的成員變量 * getDeclaredMethods()獲取的是所有該類自己聲明的成員變量 */ Field[] fs = c.getDeclaredFields(); // c.getFields(); for (int i = 0; i < fs.length; i++) { // 得到成員變量的類型 Class fieldType = fs[i].getType(); String typeName = fieldType.getName(); // 得到成員變量的名稱 String fieldName = fs[i].getName(); }" title="" data-original-title="復制">
/** * 成員變量也是對象,Field封裝了關于成員變量的操作 * getFields()獲取的是所有的public的成員變量 * getDeclaredMethods()獲取的是所有該類自己聲明的成員變量 */ Field[] fs = c.getDeclaredFields(); // c.getFields(); for (int i = 0; i < fs.length; i++) { // 得到成員變量的類型 Class fieldType = fs[i].getType(); String typeName = fieldType.getName(); // 得到成員變量的名稱 String fieldName = fs[i].getName(); }
Java 獲取構造函數信息
/** * 構造函數也是對象 * java.lang.Constructor中封裝了構造函數的信息 */ Constructor[] cs = c.getDeclaredConstructors(); for (Constructor constructor : cs) { constructor.getName(); Class[] paramType = constructor.getParameterTypes(); }
Java 方法的反射
如何獲取某個方法:方法的名稱和方法的參數列表才能唯一決定某個方法
方法反射的操作:method.invoke(對象, 參數列表)
class A{ public void print(int a, int b){ System.out.println(a + b); } } A a = new A(); Class c = a.getClass(); try { // Method m = c.getMethod("print", new Class[]{int.class, int.class}); Method m = c.getMethod("print", int.class, int.class); // Object o = m.invoke(a, new Object[]{10, 20}); Object o = m.invoke(a, 10, 20); } catch (Exception e) { e.printStackTrace(); }
Java 類加載機制
ArrayList list = new ArrayList(); ArrayListlist1 = new ArrayList(); list == list1; // true list1.add(20); // error - 編譯檢測出錯" title="" data-original-title="復制">
ArrayList list = new ArrayList(); ArrayList list1 = new ArrayList(); list == list1; // true list1.add(20); // error - 編譯檢測出錯
反射都是編譯之后的操作,因此可看出泛型在編譯之后會被擦除
Java 中集合的泛型用于防止錯誤輸入,只在編譯階段有效,繞過編譯則無效
Class c = list1.getclass(); try { Method m = c.getMethod("add", Object.class); m.invoke(list1, 20); // correct - 繞過編譯操作就繞過了泛型 } catch (Exception e) { e.printStackTrace(); }
總結
以上是生活随笔為你收集整理的java反射泛型类型,【Java反射】Java 泛型基础的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 芝麻信用有什么等级
- 下一篇: java怎么让表格的字段相乘,excel