Skip to content

Commit cf5d1c8

Browse files
committed
java
1 parent 643f52c commit cf5d1c8

27 files changed

Lines changed: 589 additions & 4 deletions
119 KB
Binary file not shown.
753 KB
Binary file not shown.

src/com/yale/test/java/fanshe/ConstructorDemo.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ public static void main(String[] args) throws InstantiationException, IllegalAcc
3131
System.out.println("获取类的所有构造方法:" + conts[i]);
3232
System.out.println("获取类的所有构造方法(注意构造方法的getName方法):" + conts[i].getName());
3333
System.out.println("得到构造方法的修饰符public还是别的什么,返回的是数字:" + conts[i].getModifiers());
34+
int m = conts[i].getModifiers();
35+
System.out.println(Modifier.isFinal(m));
36+
System.out.println(Modifier.isPublic(m));
37+
System.out.println(Modifier.isProtected(m));
38+
System.out.println(Modifier.isPrivate(m));
39+
System.out.println(Modifier.isStatic(m));
3440
System.out.println("得到构造方法的修饰符public还是别的什么,Modifier类里面定义了数字对应的中文:" + Modifier.toString(conts[i].getModifiers()));
3541
Class<?>[] params = conts[i].getParameterTypes();
3642
for (int y=0;y<params.length; y++) {
@@ -45,6 +51,16 @@ public static void main(String[] args) throws InstantiationException, IllegalAcc
4551

4652
}
4753

54+
55+
/*
56+
*
57+
getConstructor(Class...):获取某个public的Constructor;
58+
getDeclaredConstructor(Class...):获取某个Constructor;
59+
getConstructors():获取所有public的Constructor;
60+
getDeclaredConstructors():获取所有Constructor。
61+
* 注意Constructor总是当前类定义的构造方法,和父类无关,因此不存在多态的问题。
62+
* 调用非public的Constructor时,必须首先通过setAccessible(true)设置允许访问。setAccessible(true)可能会失败。
63+
*/
4864
Class<?> per = PersonThir.class;
4965
//现在明确表示取的指定参数类型的构造方法
5066
Constructor<?> cont = per.getConstructor(String.class, int.class);

src/com/yale/test/java/fanshe/FiledDemo.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ public static void main(String[] args) throws ClassNotFoundException, NoSuchFiel
2828

2929
System.out.println("--------------------------------------------");
3030
Field scField = cls.getDeclaredField("school");//得到指定name的属性
31+
System.out.println("得到属性的类型:" + scField.getType());
3132
System.out.println("得到属性的类型:" + scField.getType().getName());
3233
System.out.println("得到属性的类型:" + scField.getType().getSimpleName());
3334

@@ -38,6 +39,8 @@ public static void main(String[] args) throws ClassNotFoundException, NoSuchFiel
3839
* Class com.yale.test.java.fanshe.FiledDemo can not access a member of class
3940
* com.yale.test.java.fanshe.FieldTe with modifiers "private"
4041
* 但是使用scField.setAccessible(true);
42+
* 此外,setAccessible(true)可能会失败。如果JVM运行期存在SecurityManager,那么它会根据规则进行检查,有可能阻止setAccessible(true)。
43+
* 例如,某个SecurityManager可能不允许对java和javax开头的package的类调用setAccessible(true),这样可以保证JVM核心库的安全。
4144
*/
4245
scField.setAccessible(true);//设置为true就可以访问private属性
4346
scField.set(obj, "四中");//通过反射给FieldTe对象的属性设置值

src/com/yale/test/java/fanshe/MethodDemo.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,16 @@ public class MethodDemo {
2424
public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException {
2525
//Class<?> cls = Per.class;这个更下面这个是一样的
2626
Class<?> cls = Class.forName("com.yale.test.java.fanshe.Per");
27+
/*
28+
* Method getMethod(name, Class...):获取某个public的Method(包括父类)
29+
* Method getDeclaredMethod(name, Class...):获取当前类的某个Method(不包括父类)
30+
* Method[] getMethods():获取所有public的Method(包括父类)
31+
* Method[] getDeclaredMethods():获取当前类的所有Method(不包括父类)
32+
* getName():返回方法名称,例如:"getScore";
33+
* getReturnType():返回方法返回值类型,也是一个Class实例,例如:String.class;
34+
* getParameterTypes():返回方法的参数类型,是一个Class数组,例如:{String.class, int.class};
35+
* getModifiers():返回方法的修饰符,它是一个int,不同的bit表示不同的含义。
36+
*/
2737
Method[] met = cls.getMethods();
2838
for (int i=0;i<met.length;i++) {
2939
System.out.println("这里会把Object父类的方法也打印出来:" + met[i]);
@@ -43,6 +53,19 @@ public static void main(String[] args) throws InstantiationException, IllegalAcc
4353
Method getMethod = cls.getMethod("get" + initcap(attribute));
4454
Object ret = getMethod.invoke(obj);//相当于Person对象.getName()
4555
System.out.println("通过反射调用对象的方法得到的返回值" + ret);
56+
57+
/*
58+
* 如果获取到的Method表示一个静态方法,调用静态方法时,由于无需指定实例对象,所以invoke方法传入的第一个参数永远为null。我们以Integer.parseInt(String)为例:
59+
*/
60+
Method m= Integer.class.getMethod("parseIne", String.class);
61+
Integer res = (Integer)m.invoke(null, "99");
62+
System.out.println(res);
63+
64+
/*
65+
* 和Field类似,对于非public方法,我们虽然可以通过Class.getDeclaredMethod()获取该方法实例,但直接对其调用将得到一个IllegalAccessException。
66+
* 为了调用非public方法,我们通过Method.setAccessible(true)允许其调用:
67+
* 使用反射调用方法时,仍然遵循多态原则:即总是调用实际类型的覆写方法(如果存在)。
68+
*/
4669
}
4770
public static String initcap(String str) {
4871
return str.substring(0, 1).toUpperCase() + str.substring(1);

src/com/yale/test/java/fanshe/SuperClassDemo.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,25 @@ class Person implements IMessageSec, IFruitSec {
1515
public class SuperClassDemo {
1616

1717
public static void main(String[] args) {
18+
/*
19+
* 除Object外,其他任何非interface的Class都必定存在一个父类类型。
20+
*/
1821
Class<?> cls = Person.class;
1922
System.out.println("得到类的包名称:" + cls.getPackage().getName());
2023
System.out.println("得到父类的名称:Class<? super T> " + cls.getSuperclass().getName());
24+
/*
25+
* 要特别注意:getInterfaces()只返回当前类直接实现的接口类型,并不包括其父类实现的接口类型:
26+
* 此外,对所有interface的Class调用getSuperclass()返回的是null,获取接口的父接口要用getInterfaces():
27+
* 如果一个类没有实现任何interface,那么getInterfaces()返回空数组。
28+
*/
2129
Class<?>[] inArr = cls.getInterfaces();
2230
for (int x=0;x<inArr.length; x++) {
2331
System.out.println("得到的类实现的接口名称:" + inArr[x].getName());
2432
}
33+
34+
//如果是两个Class实例,要判断一个向上转型是否成立,可以调用isAssignableFrom():
35+
System.out.println("向上转型能否成功:Person可以向上转型给IMessageSec:" + IMessageSec.class.isAssignableFrom(Person.class));
36+
System.out.println("向上转型能否成功:IMessageSec不可以向上转型给Person:" + cls.isAssignableFrom(IMessageSec.class));
37+
System.out.println("向上转型能否成功:" + cls.isAssignableFrom(Integer.class));
2538
}
2639
}

src/com/yale/test/java/fanshe/annotation/AnnotationDemo.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,17 @@
77
* Annotation要想学习Annotation需要利用反射技术,
88
* Annotation可以说是整个JDK发展的一项重要技术,因为从现在的开发来讲,Annotation的使用已经变得广谱化,只要有项目基本上都会有Annotation的出现。
99
* 阿里云 魔乐科技 课时18 Annotation(代码开发逻辑)
10+
* 注释会被编译器直接忽略,注解则可以被编译器打包进入class文件,因此,注解是一种用作标注的“元数据”。
11+
* 从JVM的角度看,注解本身对代码逻辑没有任何影响,如何使用注解完全由工具决定。
12+
* Java的注解可以分为三类:
13+
第一类是由编译器使用的注解,例如:
14+
@Override:让编译器检查该方法是否正确地实现了覆写;
15+
@SuppressWarnings:告诉编译器忽略此处代码产生的警告。
16+
这类注解不会被编译进入.class文件,它们在编译后就被编译器扔掉了。
17+
第二类是由工具处理.class文件使用的注解,比如有些工具会在加载class的时候,对class做动态修改,实现一些特殊的功能。
18+
这类注解会被编译进入.class文件,但加载结束后并不会存在于内存中。这类注解只被一些底层库使用,一般我们不必自己处理。
19+
第三类是在程序运行期能够读取的注解,它们在加载后一直存在于JVM中,这也是最常用的注解。例如,一个配置了@PostConstruct的方法会在调用
20+
构造方法后自动被调用(这是Java代码读取该注解实现的功能,JVM并不会识别该注解)。
1021
* @author dell
1122
*/
1223
public class AnnotationDemo {
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package com.yale.test.java.fanshe.annotation;
2+
3+
import java.lang.annotation.ElementType;
4+
import java.lang.annotation.Retention;
5+
import java.lang.annotation.RetentionPolicy;
6+
import java.lang.annotation.Target;
7+
import java.lang.reflect.Field;
8+
9+
public class AnnotationEg {
10+
11+
@Range(min=1, max=20)
12+
public String name;
13+
14+
@Range(max=10)
15+
public String city;
16+
17+
public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException {
18+
/*
19+
* 注解如何使用,完全由程序自己决定。例如,JUnit是一个测试框架,它会自动运行所有标记为@Test的方法。
20+
* 我们来看一个@Range注解,我们希望用它来定义一个String字段的规则:字段长度满足@Range的参数定义:
21+
* 但是,定义了注解,本身对程序逻辑没有任何影响。我们必须自己编写代码来使用注解。这里,我们编写一个Person实例的检查方法,
22+
* 它可以检查Person实例的String字段长度是否满足@Range的定义:
23+
* 这样一来,我们通过@Range注解,配合check()方法,就可以完成Person实例的检查。
24+
* 注意检查逻辑完全是我们自己编写的,JVM不会自动给注解添加任何额外的逻辑。
25+
*/
26+
AnnotationEg ae = new AnnotationEg();
27+
ae.name="";
28+
ae.check(ae);
29+
}
30+
31+
void check(AnnotationEg ae) throws IllegalArgumentException, IllegalAccessException {
32+
for (Field field : ae.getClass().getFields()) {
33+
Range range = field.getAnnotation(Range.class);
34+
if (range != null) {
35+
Object value = field.get(ae);
36+
if (value instanceof String) {
37+
int len = ((String) value).length();
38+
if (len < range.min() || len > range.max()) {
39+
throw new IllegalArgumentException("Invalid field:" + field.getName());
40+
}
41+
}
42+
}
43+
}
44+
}
45+
46+
}
47+
48+
@Retention(RetentionPolicy.RUNTIME)
49+
@Target(ElementType.FIELD)
50+
@interface Range {
51+
int min() default 0;
52+
int max() default 255;
53+
}

0 commit comments

Comments
 (0)