This commit is contained in:
MYP 2021-07-12 16:23:57 +08:00
commit bab3998b51
8 changed files with 654 additions and 152 deletions

View File

@ -1,43 +1,90 @@
# 10. 注解
## 10.1 什么是注解
注解,一种元数据形式,提供有关程序的数据,该数据不属于程序本身。注释对其注释的代码的操作没有直接影响。
注解的语法:
```java
@注解类型名
```
*注释*,一种元数据形式,提供有关程序的数据,该数据不属于程序本身。注释对其注释的代码的操作没有直接影响。
注释有多种用途,其中包括:
- **编译器信息**——**编译器**可以使用注释来检测错误或抑制警告。
- **编译时和部署时处理**——软件工具可以处理注释信息以生成代码、XML 文件等。
- **运行时处理**——一些注解可以在运行时检查。
### 内置的注解
Java 定义了一套注解,共有 7 个3 个在 java.lang 中,剩下 4 个在 java.lang.annotation 中。
**作用在代码的注解是**
- @Override - 检查该方法是否是重写方法。如果发现其父类,或者是引用的接口中并没有该方法时,会报编译错误。
- @Deprecated - 标记过时方法。如果使用该方法,会报编译警告。
- @SuppressWarnings - 指示编译器去忽略注解中声明的警告。
作用在其他注解的注解(或者说 元注解)是:
- @Retention - 标识这个注解怎么保存是只在代码中还是编入class文件中或者是在运行时可以通过反射访问。
- @Documented - 标记这些注解是否包含在用户文档中。
- @Target - 标记这个注解应该是哪种 Java 成员。
- @Inherited - 标记这个注解是继承于哪个注解类(默认 注解并没有继承于任何子类)
从 Java 7 开始,额外添加了 3 个注解:
- @SafeVarargs - Java 7 开始支持,忽略任何使用参数为泛型变量的方法或构造函数调用产生的警告。
- @FunctionalInterface - Java 8 开始支持,标识一个匿名函数或函数式接口。
- @Repeatable - Java 8 开始支持,标识某注解可以在同一个声明上使用多次。
* 编译前:为编译器提供编译检查的依据,辅助检查代码错误或抑制检查异常。
* 编译中或发布时:给编译器提供信息生成代码或给其他工具提供信息生成文档等。
* 运行时:在运行过程中提供信息给解释器,辅助程序执行。
* 注解经常和反射结合起来用,多用于框架中。
## 自定义注解
## 10.2 内置的注解
日常开发中我们使用class、interface比较多而注解和它们一样也是一种类的类型他是用的修饰符为 @interface
### 10.2.1 Override
@元注解
* 加在方法前
* 表示重写(覆盖)父类的方法;
* 如果重写(覆盖)有错误,则报错。
* 因此重写父类方法,请加上@Override注解。
```java
class Parent {
String name;
public Parent(){}
public Parent(String name)
{
this.name = name;
}
public void sayHello()
{
System.out.println("你好,我是" + name )
}
}
public class Child extends Parent
{
String name;
public Child{}
@Override
public void sayHello(String str)
{
//这里会报错
super.sayHello();
System.out.println("Hello,im Datawhale");
}
}
/**
本段代码则不会提示错误
public class Child extends Parent
{
String name;
public Child{}
@Override
public void sayHello()
{
super.sayHello();
System.out.println("Hello,im Datawhale");
}
}
**/
```
## 10.3 自定义注解
日常开发中我们使用class、interface比较多而注解和它们一样也是一种类的类型他是用的修饰符为 @interface @元注解
使用@interface自定义注解时自动继承了java.lang.annotation.Annotation接口语法如下
```java
public @interface MyTestAnnotation {
@ -46,3 +93,33 @@ public @interface MyTestAnnotation {
```
## 10.4 元注解
元注解负责注解其他注解。Java5.0定义了4个标准的meta-annotation类型它们被用来提供对其它 annotation类型作说明。
@Target,
@Retention,
@Documented,
@Inherited
@Target说明了Annotation所修饰的对象范围Annotation可被用于 packages、types类、接口、枚举、Annotation类型、类型成员方法、构造方法、成员变量、枚举值、方法参数和本地变量如循环变量、catch参数
 取值(ElementType)有:
  1.CONSTRUCTOR:用于描述构造器
  2.FIELD:用于描述域
  3.LOCAL_VARIABLE:用于描述局部变量
  4.METHOD:用于描述方法
  5.PACKAGE:用于描述包
  6.PARAMETER:用于描述参数
  7.TYPE:用于描述类、接口(包括注解类型) 或enum声明
```java
@Target(ElementType.TYPE)
public @interface Table {
}
@Target(ElementType.FIELD)
public @interface NoDBColumn {
}
```
@Retention定义了该Annotation被保留的时间长短某些Annotation仅出现在源代码中而被编译器丢弃而另一些却被编译在class文件中编译在class文件中的Annotation可能会被虚拟机忽略而另一些在class被装载时将被读取请注意并不影响class的执行因为Annotation与class在使用上是被分离的

View File

@ -5,7 +5,6 @@
> 泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。
>
> 泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)。也就是说在泛型使用过程中,操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。
>
@ -70,9 +69,44 @@ java: 对于add(int), 找不到合适的方法
泛型使得代码可以被不同类型的对象重用
## 11.2 泛型方法
## 11.2 泛型类
一个泛型类就是拥有一个或者多个类型变量的类。下面看一个简单例子:
```java
public class test {
public static class Point<T> {
private T var;
public void setVar(T x) {
this.var = x;
}
public T getVar() {
return this.var;
}
}
public static void main(String[] args){
Point<Float> p = new Point<Float>() ;
p.setVar(new Float(100.12f)) ;
System.out.println(p.getVar());
}
}
```
括号里面的T是形式类型参数可以随意指定当类被使用的时候就会使用具体的实际类型参数。
需要注意的是,泛型类只能用在成员变量上,并且只能使用引用类型。
## 11.3 泛型方法
下面是定义泛型方法的规则:
@ -81,43 +115,22 @@ java: 对于add(int), 找不到合适的方法
- 类型参数能被用来声明返回值类型,并且能作为泛型方法得到的实际参数类型的占位符。
- 泛型方法体的声明和其他方法一样。注意类型参数只能代表引用型类型不能是原始类型像int,double,char的等
```
/**
* 泛型方法的基本介绍
* @param tClass 传入的泛型实参
* @return T 返回值为T类型
* 说明:
* 1public 与 返回值中间<T>非常重要,可以理解为声明此方法为泛型方法。
* 2只有声明了<T>的方法才是泛型方法,泛型类中的使用了泛型的成员方法并不是泛型方法。
* 3<T>表明该方法将使用泛型类型T此时才可以在方法中使用泛型类型T。
* 4与泛型类的定义一样此处T可以随便写为任意标识常见的如T、E、K、V等形式的参数常用于表示泛型。
*/
public <T> T genericMethod(Class<T> tClass)throws InstantiationException ,
IllegalAccessException{
T instance = tClass.newInstance();
return instance;
}
```
## 11.3 泛型类
一个泛型类就是拥有一个或者多个类型变量的类。下面看一个简单例子:
```java
ublic class Generic<T>{
//key这个成员变量的类型为T,T的类型由外部指定
private T key;
public Generic(T key) { //泛型构造方法形参key的类型也为TT的类型由外部指定
this.key = key;
public class MethodTest {
int var = 100;
String varStr = "Hello Datawhale";
public <T> T Method(T a) {
return a;
}
public static void main(String[] args) {
MethodTest t=new MethodTest();
System.out.println(t.<Integer>Method(t.var));
System.out.println(t.<String>Method(t.varStr));
}
public T getKey(){ //泛型方法getKey的返回值类型为TT的类型由外部指定
return key;
}
}
```
@ -126,44 +139,57 @@ ublic class Generic<T>{
```
//定义一个泛型接口
public interface Generator<T> {
public T next();
```java
class InfoImpl implements Info<String>{ // 定义泛型接口的子类
private String var ; // 定义属性
public InfoImpl(String var){ // 通过构造方法设置属性内容
this.setVar(var) ;
}
@Override
public void setVar(String var){
this.var = var ;
}
@Override
public String getVar(){
return this.var ;
}
}
public class GenericsDemo24{
public void main(String arsg[]){
InfoImpl i = new InfoImpl("harvic");
System.out.println(i.getVar()) ;
}
};
```
## 11.5 类型通配符
类型通配符一般是使用?代替具体的类型参数。例如 **List<?>** 在逻辑上是**List<String>,List<Integer>** 等所有List<具体类型实参>的父类。
类型通配符一般是在不确定具体参数时候,使用?代替。?表示未知类型,类型参数赋予不确定值,只能用在声明类型、方法参数上,不能用在定义泛型类上
```java
public class match {
public static void test(List<?> list) {
```
import java.util.*;
List<?> list2;
list2 = new ArrayList<String>();
list2 = new ArrayList<Integer>();
list2 = new ArrayList<Object>();
public class GenericTest {
}
public static void main(String[] args) {
List<String> name = new ArrayList<String>();
List<Integer> age = new ArrayList<Integer>();
List<Number> number = new ArrayList<Number>();
name.add("icon");
age.add(18);
number.add(314);
getData(name);
getData(age);
getData(number);
test(new ArrayList<String>());
test(new ArrayList<Integer>());
}
public static void getData(List<?> data) {
System.out.println("data :" + data.get(0));
}
}
```

View File

@ -1,11 +1,9 @@
# 反射
# 9. 反射
## 反射概述
## 9.1 反射概述
JAVA反射是在运行状态中对于任意一个类都能够知道这个类的所有属性和方法对于任意一个对象都能够调用它的任意方法和属性这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
**反射的功能**
1. 在运行时获取任意一个对象所属的类型信息,包括修饰符、泛型、父类、实现的接口、注解等;
@ -13,8 +11,6 @@ JAVA反射是在运行状态中对于任意一个类都能够知道这个
3. 在运行时获取任意一个类所具有的构造方法、成员变量和方法;
4. 在运行时访问任意一个对象的成员变量和方法;
**反射的应用**
1. 通过使用类全名创建类实例来使用外部用户定义的类。
@ -38,20 +34,26 @@ JAVA反射是在运行状态中对于任意一个类都能够知道这个
**使用反射的注意事项**
反射是强大的,但不应滥用。如果可以在不使用反射的情况下进行操作,则优选避免使用反射。
反射增加了JVM的系统开销性能上比不使用反射慢。
反射可能违反某些安全策略。
反射允许访问私有成员,打破了封装,可能破坏可移植性。
## 9.2 使用反射
## Class类
### 9.2.1 Class类
java.lang.Class类是所有Reflection API的切入点是所有反射操作的入口。
在Java程序运行过程中对程序中每种类型的对象Java虚拟机都会实例化一个不可变的java.lang.Class实例每个对象都是引用或者原始类型。
引用类型都继承自java.lang.Object。 类,枚举,数组和接口都是引用类型。
原始类型包括booleanbyteshortintlongcharfloat和double
反射机制里主要会用到以下四种类
1.java.lang.Class.java类对象
2.java.lang.reflect.Constructor.java类的构造器对象
3.java.lang.reflect.Method.java类的方法对象
4.java.lang.reflect.Field.java类的属性对象
@ -59,70 +61,135 @@ java.lang.Class类是所有Reflection API的切入点是所有反射操作的
**1.获取Class实例的三种方法最常用的是第3种**
对象.getClass()
类型名.class
Class.forName()
1. 对象.getClass()
2. 类型名.class
3. Class.forName()
示例代码于code/ClassEx.java
**2.获取类的成员**
**2.用Class实例创建对象**
这时候就用到了java.lang.reflect.Field.java类。一个Field提供类或接口中一个成员变量属性的信息也可以动态访问。
Class中提供了两类用于访问成员变量成员方法和构造方法的方法
1. 列出所有成员的方法
2. 根据名字搜索特定成员的方法
```java
//2.1通过newInstence(),此方式只适用于无参构造
Phone instance1 = (Phone) clazz1.newInstance();
//2.2先调用构造器再通过newInstence()创建
Constructor<?>[] cons = clazz1.getConstructor();
//假设第一个为无参构造
Phone instance2 = cons[0].newInstance();
//假设第二个构造方法为两个String类型参数
Phone instance3= cons[1].newInstance("s1","s2");
public Field getDeclaredField(String name)
//根据名字获取类中定义的成员变量,不包括继承父类的成员
public Field getField(String name)
//根据名字获取类中定义的公有成员变量,包括继承父类的成员
public Field[] getDeclaredFields()
//获取类中声明的所有成员变量返回Field[]类型,不含继承父类的成员
public Field[] getFields()
//获取类中声明的所有公有成员变量返回Field[]类型
```
(示例代码于 code/RefEx)
**3.获取类的成员方法**
```java
public Method getDeclaredMethod(String name,
Class<?>... parameterTypes)
//根据名字获取类中定义的成员方法,不包括继承父类的成员方法
public Method getMethod(String name,
Class<?>... parameterTypes)
//根据名字获取类中定义的公有成员方法,包括继承父类的成员方法
public Method[] getDeclaredMethods()
//获取类中声明的所有成员方法返回Method[]类型,不含继承父类的成员
public Method[] getMethods()
//获取类中声明的所有公有成员方法返回Method[]类型
```
(示例代码于 code/RefEx)
**4.获取类的构造方法**
```java
public Constructor<T> getDeclaredConstructor(Class<?>… parameterTypes)
//根据参数类型列表获取类中定义的构造方法
public Constructor<T> getConstructor(Class<?>… parameterTypes)
//根据参数类型列表获取类中定义的公有构造方法
public Constructor<?>[] getDeclaredConstructors()
//获取类中声明的所有构造方法返回Constructor[]类型
public Constructor<?>[] getConstructors()
//获取类中声明的所有公有构造方法返回Constructor[]类型
```
**3.获取指定属性Field和所有的属性Field**
获取成员变量的类型信息(了解)。
```
Class<?> c = Class.forName(className);
Field field = c.getField(fieldName);
Class typeClass = field.getType();
Type type = field.getGenericType();
```
**5.调用成员方法**
**4.用反射的方式给对象的属性设置值,获取对象的属性值**
获取指定的方法Method和所有的方法Method
用反射的方式调用方法,获取调用的方法的返回值
获取指定的构造方法Constructor和所有构造方法Constructor
**Method.invoke(Object obj, Object... args)**实现方法调用,多用于不得不用反射的的情况下。
第一个参数是调用这个方法的类实例如果该方法是静态的第一个参数为null
后面几个参数是该方法的参数,如果方法没有参数,可以省略
**通过Constructor实例创建对象。**
调用成员方法的案例:示例代码见 code/Deet.java
**6.用反射的方式给对象的属性设置值,获取对象的属性值**
* 给定类的实例,可以使用反射来设置该类实例中成员变量的值。
* 通常是以常规方式无法设置的情况下才这样操作。
* 因为这种访问违反了类的封装性的设计意图,耗费额外的系统开销,所以应该尽可能的酌情使用。
(示例代码见 code/Test.java)
7**.通过Constructor实例创建对象。**
创建类实例(类对象)(重点掌握):
常规情况下是使用new操作符调用类的构造方法来创建类实例
```
```java
Date date = new Date
```
使用反射创建类实例有两种方法:
```
```java
Class.newInstance()
//只能调用类的无参数的非私有构造方法
//抛出构造方法的异常
Constructor.newInstance(Object... initargs)
//可以调用类的任何构造方法
//用InvocationTargetException封装异常来抛出
```
Class.newInstance()
只能调用类的无参数的非私有构造方法
抛出构造方法的异常
Constructor.newInstance(Object... initargs)
可以调用类的任何构造方法
用InvocationTargetException封装异常来抛出
**使用反射的注意事项**
反射是强大的,但不应滥用。如果可以在不使用反射的情况下进行操作,则优选避免使用反射。
反射增加了JVM的系统开销性能上比不使用反射慢。
反射可能违反某些安全策略。
反射允许访问私有成员,打破了封装,可能破坏可移植性。

View File

@ -7,7 +7,7 @@
| 赖桂彬 | 广州城市理工学院 | |
| 梁家晖 | 广州城市理工学院Datawhale成员 | https://github.com/leungkafai |
| 陈玉林 | 广州城市理工学院 | |
| 潘梓琪 | | |
| 潘梓琪 | 广州城市理工学院 | |
| 周思阳 | 武汉理工大学,物流管理硕士 | https://github.com/suifengyougu |
@ -31,41 +31,41 @@
- 组队、修改群昵称
- 熟悉打卡规则。
### Task012天
### Task01Java简介与环境配置2天
0.java简介与安装配置
1.基本数据类型与变量
### Task022天
### Task02初始Java语言基础2天
2.运算符和表达式
3.控制流程
### Task031天
### Task03Java数组1天
4.数组
### Task043天
### Task04面向对象编程基础3天
5.类与方法
6.继承与多态
### Task053天
### Task05面向对象核心技术3天
7.抽象类与接口
8.异常处理
### Task063天
### Task06反射与注释3天
9.反射
10.注解
### Task07: (2天)
### Task07: 泛型2天
11.泛型

113
Java/code/ClassEx.java Normal file
View File

@ -0,0 +1,113 @@
package ;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
enum E { A, B };//枚举类型E
public class ClassEx {
public static void main(String[] args) throws Exception {
//第1种获取Class实例的方法 对象名.getClass()原始类型接口类型对应的Class实例不能用这种方法获取
//类类型
Class c = "foo".getClass();
System.out.println(c);
c = System.out.getClass();
System.out.println(c);
Date date=new Date();
c=date.getClass();
System.out.println(c);
//接口类型
List<Date> array=new ArrayList<Date>();
c=array.getClass();
System.out.println(c);
//数组类型
int[] a=new int[10];
c=a.getClass();
System.out.println(c+" "+c.getCanonicalName());
char[] b=new char[10];
c=b.getClass();
System.out.println(c+" "+c.getName());
double[] d=new double[10];
c=d.getClass();
System.out.println(c);
long[] l=new long[10];
c=l.getClass();
System.out.println(c);
Date[] f=new Date[10];
c=f.getClass();
System.out.println(c+" "+c.getCanonicalName());
//枚举类型
E e=E.A;
c=e.getClass();
System.out.println(c);
System.out.println("*****************************");
//基本类型编译错误
//int a=10;
//c=a.getClass();
//第2种获取Class实例的方法 类型名.class所有类型对应的Class实例都可以用这种方法获取
c=String.class;
System.out.println(c);
c=Date.class;
System.out.println(c);
c=List.class;
System.out.println(c);
c=int.class;
System.out.println(c);
c=int[][].class;
System.out.println(c);
c=Date[][].class;
System.out.println(c);
c=E.class;
System.out.println(c);
System.out.println("*****************************");
//第3种获取Class实例的方法 Class.forName(类全名字符串)原始类型对应的Class实例不可以用这种方法获取
c=Class.forName("java.lang.String");
System.out.println(c);
c=Class.forName("java.util.List");
System.out.println(c);
c=Class.forName("[I");//int数组类型int[]
System.out.println(c);
c = Class.forName("[D");//double型数组double[]
System.out.println(c);
c = Class.forName("[[Ljava.lang.String;");//String二维数组String[][]
System.out.println(c);
c=Class.forName("类.E");
System.out.println(c);
System.out.println("*****************************");
//基本类型包装类中的TYPE成员的值是基本类型对应的Class类实例
c=Double.TYPE;
System.out.println(c);
c=Void.TYPE;
System.out.println(c);
}
}

54
Java/code/Deet.java Normal file
View File

@ -0,0 +1,54 @@
package 方法;
import static java.lang.System.out;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Locale;
public class Deet<T> {
private boolean testDeet(Locale l) {
out.format("Locale = %s, Language Code = %s%n", l.getDisplayName(), l.getLanguage());
return true;
}
private boolean testFoo(Locale l) {
return false;
}
private boolean testBar() {
return true;
}
public static void main(String... args) {
try {
//获取Deet类的Class实例
Class<?> c = Deet.class;
//有Class实例创建一个类对象
Object t = c.newInstance();
//获取Class实例对应的类型声明的所有的方法
Method[] allMethods = c.getDeclaredMethods();
for (Method m : allMethods) {
String mname = m.getName();//获取方法的名字
//如果方法的名字不以test开头或者返回类型不是boolean型
if (!mname.startsWith("test") || (m.getReturnType() != boolean.class)) {
continue;
}
//获取方法的所有参数类型
Type[] pType = m.getGenericParameterTypes();
//如果有参数并且第一个参数是Locale类型
if ((pType.length != 1) || Locale.class.isAssignableFrom(pType[0].getClass())) {
continue;
}
out.format("调用 %s()%n", mname);
try {
//调用方法o是方法返回值
Object o = m.invoke(t, Locale.CHINA);
out.format("%s() 返回 %b%n%n", mname, (Boolean) o);
} catch (InvocationTargetException x) {
x.printStackTrace();
} }
} catch (InstantiationException x) {
x.printStackTrace();
} catch (IllegalAccessException x) {
x.printStackTrace();
}
}
}

78
Java/code/RefEx.java Normal file
View File

@ -0,0 +1,78 @@
package test;
import static java.lang.System.out;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.ArrayList;
public class RefEx {
public static void main(String[] args) {
// TODO Auto-generated method stub
String s="hello";
Class c=s.getClass();//获取类型
System.out.println(c);
String modifiers=Modifier.toString(c.getModifiers());//获取修饰符
System.out.println(modifiers);
TypeVariable<?>[] tv = c.getTypeParameters();//获取泛型类型参数
if (tv.length != 0) {
out.format(" ");
for (TypeVariable<?> t : tv)
out.format("%s ", t.getName());
out.format("%n%n");
} else {
out.format(" -- No Type Parameters --%n%n");
}
Class superclass=c.getSuperclass();//获取类型的父类
System.out.println(superclass);
Type[] intfs = c.getGenericInterfaces();//获取类实现的接口
if (intfs.length != 0) {
for (Type intf : intfs)
out.format(" %s%n", intf.toString());
out.format("%n");
} else {
out.format(" -- No Implemented Interfaces --%n%n");
}
Annotation[] ann = c.getAnnotations();//获取类的注解
if (ann.length != 0) {
for (Annotation a : ann)
out.format(" %s%n", a.toString());
out.format("%n");
} else {
out.format(" -- No Annotations --%n%n");
}
Constructor[] cons=c.getDeclaredConstructors();//获取类的构造方法
for(Constructor con:cons){
System.out.println(con.toGenericString());
}
out.format("%n%n");
Field[] fs=c.getDeclaredFields();//获取类的数据成员成员变量
for(Field f:fs){
System.out.println(f.toGenericString());
}
out.format("%n%n");
Method[] ms=c.getMethods();//获取类的公有成员方法包含从父类继承的
for(Method m:ms){
System.out.println(m.toGenericString());
}
out.format("%n%n");
}
}

87
Java/code/Test.java Normal file
View File

@ -0,0 +1,87 @@
package test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test {
public static String classname="类.Student";
public static String fieldname="name";
public static String methodname="setName";
public static String[] mptypes= {"java.lang.String"};
public static Object fvalue=new String("xiaolin");
public static Object mp1=new String("xiaohong");
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
Class c=Class.forName(classname);//根据类名字符串获得类对应的Class实例
//第一种用反射创建类对象的方法相当于调用类的无参数构造方法
Object o=c.newInstance();//Student o=new Student();
//使用反射访问类对象的属性给属性设置值获取属性的值
Field f=c.getDeclaredField(fieldname);//根据Field名获得Field对象
f.setAccessible(true);
f.set(o,fvalue);//o.name="xiaolin";使用反射给o对象的f代表的属性设置值为发value的值
System.out.println(f.get(o));//获取o对象的f属性对应的值并输出
@SuppressWarnings("unchecked")
//使用反射调用对象的方法
//使用反射根据方法名和参数类型参数数量来获取具体某个方法
Method m=c.getDeclaredMethod(methodname, Class.forName(mptypes[0]));//String.class
//方法的调用调用o对象的m方法方法的实际参数是mp1mo是方法调用的返回值
Object mo=m.invoke(o,mp1);//o.setName("xiaohong");
System.out.println(mo);
//调用了o对象名为setAge参数有1个类型是int型的方法实际参数是21
m=c.getDeclaredMethod("setAge", int.class);
m.invoke(o, 21);
System.out.println(o);
/*Method m=c.getDeclaredMethod(methodname);
Object mo=m.invoke(o);
System.out.println(mo);
System.out.println(f.get(o));*/
@SuppressWarnings({ "unchecked", "rawtypes" })
//第二种用反射创建类对象的方法先获取具体的Constructor再用Constructor去创建对象
Constructor con=c.getDeclaredConstructor(String.class,int.class);//根据构造方法参数类型来获取某个构造方法
Object o1=con.newInstance("Mary",20);
//用Constructor创建类对象相当于Student o1=new Student("Mary",20);
System.out.println(o1);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}