1申钩,可變長度參數(shù)
語法:類型... (注意:一定是3個點)
可變長度參數(shù)要求參數(shù)個數(shù)是:0-N個饿凛。
可變長度參數(shù)在參數(shù)列表中必須在最后一個位置上窟却,而且可變長度參數(shù)只能有1個遇汞。
可變長度參數(shù)可以當(dāng)做一個數(shù)組來看
代碼示例
public class ArgsTest {
public static void main(String[] args) {
m(100,"abc");
m(200,"abc","def","xyz");
// 傳數(shù)組
String[] strings = {"我","是","中","國","人"};
m(300,strings);
}
public static void m(int a, String... args){
System.out.println(a);
// args有l(wèi)ength屬性未妹,說明args是一個數(shù)組
// 可以將可變長度參數(shù)當(dāng)做一個數(shù)組來看。
for (int i = 0;i < args.length;i++){
System.out.println(args[i]);
}
}
}
2空入,反射方法Method(了解內(nèi)容)
2.1络它,通過反射機制獲取一個對象的方法
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class ReflectTest08 {
public static void main(String[] args) throws Exception {
Class us = Class.forName("com.javaSE.reflects.UserService");
// 獲取所有的Method(包括私有的)
Method[] methods = us.getDeclaredMethods();
// 遍歷Method
for (Method method : methods){
// 獲取修飾符列表
System.out.println("修飾符列表:" + Modifier.toString(method.getModifiers()));
// 獲取方法返回值類型
System.out.println("返回值類型:" + method.getReturnType().getName());
// 獲取方法名
System.out.println("方法名:" + method.getName());
// 獲取方法的參數(shù)列表
Class[] parameterTypes = method.getParameterTypes();
for (Class pt : parameterTypes){
// 獲取參數(shù)類型名字
System.out.println("參數(shù)類型名字:" + pt.getSimpleName());
}
}
System.out.println("-------------通過反射機制,反編譯一個類的方法---------------------------------------------");
// 通過反射機制歪赢,反編譯一個類的方法Method
fbyMethod();
}
private static void fbyMethod() throws ClassNotFoundException {
Class us = Class.forName("com.javaSE.reflects.UserService");
// 創(chuàng)建可變字符串對象
StringBuilder sr = new StringBuilder();
sr.append(Modifier.toString(us.getModifiers()) + " class " + us.getSimpleName() + "{\n");
// 獲取所有的Method(包括私有的)
Method[] methods = us.getDeclaredMethods();
for (Method method : methods){
sr.append("\t");
sr.append(Modifier.toString(method.getModifiers()));
sr.append(" ");
sr.append(method.getReturnType().getSimpleName());
sr.append(" ");
sr.append(method.getName());
sr.append("(");
for (Class c : method.getParameterTypes()) {
sr.append(c.getSimpleName());
sr.append(",");
}
// 刪除指定下標(biāo)位置的字符
sr.deleteCharAt(sr.length() - 1);
sr.append("){\n");
sr.append("\t}");
sr.append("\n");
}
sr.append("}");
System.out.println(sr);
}
}
class UserService{
/**
* 登錄方法
* @param name 用戶名
* @param password 密碼
* @return true登錄成功化戳,false登錄失敗。
*/
public boolean login(String name ,String password){
if ("admin".equals(name) && "123".equals(password)){
return true;
}
return false;
}
/**
* 退出登錄
*/
public void loginOut(){
System.out.println("已成功退出登錄埋凯!");
}
}
2.2点楼,通過反射機制調(diào)用一個對象的方法
import java.lang.reflect.Method;
public class ReflectTest09 {
public static void main(String[] args) throws Exception {
Class us = Class.forName("com.javaSE.reflects.UserService");
// 創(chuàng)建對象
Object obj = us.newInstance();
// 獲取UserService對象的方法Method
Method loginM = obj.getClass().getDeclaredMethod("login",String.class,String.class);
// 調(diào)用方法
Object invKV = loginM.invoke(obj,"admin","123");
System.out.println(invKV);
}
}
反射構(gòu)造方法
- 通過反射機制,獲取一個類的父類
- 通過反射機制递鹉,獲取一個類實現(xiàn)的所有接口
- 通過反射機制盟步,調(diào)用一個類的構(gòu)造方法
- 通過反射機制,反編譯一個類的構(gòu)造方法
代碼示例
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
public class ReflectTest10 {
public static void main(String[] args) throws Exception{
// 創(chuàng)建VipUser對象
Class cc = Class.forName("com.javaSE.reflects.VipUser");
System.out.println("-------------通過反射機制躏结,獲取一個類的父類---------------------------------------------");
Class superClass = cc.getSuperclass();
// 獲取父類名字
System.out.println(superClass.getName());
System.out.println(superClass.getSimpleName());
System.out.println("-------------通過反射機制,獲取一個類實現(xiàn)的所有接口---------------------------------------------");
Class strClass = Class.forName("java.lang.String");
// 獲取一個類實現(xiàn)的所有接口
Class[] interfaces = strClass.getInterfaces();
for (Class i : interfaces){
System.out.println(i.getName());
}
System.out.println("-------------通過反射機制狰域,調(diào)用一個類的構(gòu)造方法---------------------------------------------");
// 調(diào)用無參構(gòu)造方法
Object obj0 = cc.newInstance();
System.out.println(obj0);
// 獲取無參構(gòu)造方法
Constructor c0 = cc.getDeclaredConstructor();
Object obj00 = c0.newInstance();
System.out.println(obj00);
// 獲取帶有參數(shù)的構(gòu)造方法
Constructor c1 = cc.getDeclaredConstructor(int.class);
Constructor c2 = cc.getDeclaredConstructor(int.class,String.class);
Constructor c3 = cc.getDeclaredConstructor(int.class,String.class,String.class);
Constructor c4 = cc.getDeclaredConstructor(int.class,String.class,String.class,boolean.class);
// 調(diào)用構(gòu)造方法new對象
Object obj1 = c1.newInstance(112);
Object obj2 = c2.newInstance(112,"admin");
Object obj3 = c3.newInstance(112,"admin","2020-02-20");
Object obj4 = c4.newInstance(112,"admin","2020-02-20",true);
// 打印輸出
System.out.println(obj1);
System.out.println(obj2);
System.out.println(obj3);
System.out.println(obj4);
System.out.println("-------------通過反射機制媳拴,反編譯一個類的構(gòu)造方法---------------------------------------------");
// 創(chuàng)建可變字符串對象
StringBuilder sr = new StringBuilder();
sr.append(Modifier.toString(cc.getModifiers()) + " class " + cc.getSimpleName() + "{\n");
// 拼接構(gòu)造方法
Constructor[] cs = cc.getDeclaredConstructors();
for (Constructor c : cs){
sr.append("\t");
sr.append(Modifier.toString(c.getModifiers()));
sr.append(" ");
sr.append(cc.getSimpleName());
sr.append("(");
// 拼接參數(shù)
for (Class cp : c.getParameterTypes()){
sr.append(cp.getSimpleName());
sr.append(",");
}
if (c.getParameterTypes().length > 0){
sr.deleteCharAt(sr.length() - 1);
}
sr.append("){}\n");
}
sr.append("}");
System.out.println(sr);
}
}
class VipUser{
int no;
String name;
String birth;
boolean sex;
public VipUser() {
}
public VipUser(int no) {
this.no = no;
}
public VipUser(int no, String name) {
this.no = no;
this.name = name;
}
public VipUser(int no, String name, String birth) {
this.no = no;
this.name = name;
this.birth = birth;
}
public VipUser(int no, String name, String birth, boolean sex) {
this.no = no;
this.name = name;
this.birth = birth;
this.sex = sex;
}
@Override
public String toString() {
return "VipUser{" +
"no=" + no +
", name='" + name + '\'' +
", birth='" + birth + '\'' +
", sex=" + sex +
'}';
}
}
3,注解
1黄橘,注解:或者叫做注釋,英文單詞:Annotation
2屈溉,注釋Annotation是一種引用數(shù)據(jù)類型塞关;編譯之后也是生成.class文件
-
3,怎么自定義注解子巾,語法格式
- [修飾符列表] @interface 注解類型名{}
-
4帆赢,注解怎么使用,用在什么地方
- 1线梗,注解使用是的語法結(jié)構(gòu):
@注解類型名 - 2椰于,注解可以用在類上、屬性上仪搔、方法上瘾婿、變量上...等;注解還可以出現(xiàn)在注解類型上烤咧。
- 3偏陪,注解中的屬性是value,并且只有一個屬性,該屬性名可以省略不寫煮嫌。
- 4笛谦,注解中屬性是數(shù)組,數(shù)組中只有一個元素昌阿,大括號可以省略不寫饥脑。
- 1线梗,注解使用是的語法結(jié)構(gòu):
-
5,注解當(dāng)中的屬性類型:
- byte,short,int,long,float,double,boolean,char,String,class,枚舉類型以及以上每一種的數(shù)組形式宝泵。
-
6好啰,關(guān)于jdk lang包下的Override注解
- 這個注解只能注釋方法,是給編譯器參考的儿奶,和運行階段沒關(guān)系框往;
- 凡是java中帶有這個注解的方法,編譯器都會進行編譯檢查闯捎,如果這個方法不是重寫父類的方法椰弊,編譯器報錯。
7瓤鼻,元注解:用來標(biāo)注"注解類型"的"注解"秉版,稱為元注解。
-
8茬祷,常見的元注解類型
-
Target:用來標(biāo)注"被標(biāo)注的注解"可以出現(xiàn)在哪些位置上清焕。
- @Target(ElementType.METHOD) 表示"被標(biāo)注的注解"只能出現(xiàn)在方法上。
-
Retention:用來標(biāo)注"被標(biāo)注的注解"最終保存在哪里。
- @Retention(RetentionPolicy.SOURCE) 表示該注解只能被保留在java源文件中秸妥。
- @Retention(RetentionPolicy.CLASS) 表示該注解被保留在class文件中滚停。
- @Retention(RetentionPolicy.RUNTIME) 表示該注解被保留在class文件中,并且可以被反射機制所讀取。
-
Deprecated注解:表示標(biāo)注的內(nèi)容已過時粥惧。
- 這個注解主要是向其他程序員傳遞一個信息键畴,告知已過時,有更好的解決方案存在突雪。
-
代碼示例
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
public class AnnotationTest01 {
/*
報錯了:如果一個注釋當(dāng)中有屬性起惕,那么必須給屬性賦值(除非該屬性使用了default指定了默認值)
@MyAnnotation
public void doSome(){
}
*/
// @MyAnnotation(屬性名=屬性值)
// 需給屬性賦值
@MyAnnotation(name = "a",color = "red")
public void doSome(){
}
// 注解中的屬性是value,并且只有一個屬性,該屬性名可以省略不寫
// @AnnotationValue(value = "a")
@AnnotationValue("a")
public void doOther(){
}
public static void main(String[] args) throws Exception {
// 獲取被注解的類
Class c = Class.forName("com.javaSE.annotation.MyAnnotationTest");
//========通過反射機制,反射類注解==========================================================================
// 判斷類上面是否有@MyAnnotation2注解
System.out.println(c.isAnnotationPresent(AnnotationValue.class));// true
if (c.isAnnotationPresent(AnnotationValue.class)){
AnnotationValue av = (AnnotationValue)c.getAnnotation(AnnotationValue.class);
System.out.println("類上面的注解對象:" + av);
// 獲取注解對象的屬性
String value = av.value();
System.out.println(value);
}
//========通過反射機制,反射方法注解==========================================================================
Method method = c.getDeclaredMethod("doSome");
// 判斷該方法上是否存在注解
if (method.isAnnotationPresent(MyAnnotation2.class)){
MyAnnotation2 ma2 = (MyAnnotation2)method.getAnnotation(MyAnnotation2.class);
System.out.println("name:" + ma2.name() + ";password:" + ma2.password());
}
}
}
@AnnotationValue("測試反射類注解")
class MyAnnotationTest{
@MyAnnotation2(name = "admin",password = "123")
public void doSome(){
}
}
/**
* Target:只允許該注解可以標(biāo)注類咏删、方法
* Retention:這個注解可以被反射
*/
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation2{
String name();
String password();
}
/**
* Target:只允許該注解可以標(biāo)注類惹想、方法
* Retention:這個注解可以被反射
* value屬性的注解
*/
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface AnnotationValue{
String value();
}
@interface MyAnnotation {
/**
* 在注解中定義屬性,一下這個是MyAnnotation的name屬性
* 看著像一個方法饵婆,實際上是屬性
* @return
*/
String name();
String color();
int age() default 24; // 屬性指定默認值
}
4勺馆,開發(fā)中如何使用注解
需求:假設(shè)有一個注解叫做:Uid;這個注解只能出現(xiàn)在類上面,當(dāng)這個類上有這個注解的時候侨核,
要求這個類中必須有一個int類型的uid屬性草穆,如果沒有這個屬性就報異常,如果有正常執(zhí)行搓译。
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
public class AnnotationTest02 {
public static void main(String[] args) throws Exception {
// 獲取類
Class uc = Class.forName("com.javaSE.annotation.User");
boolean isOk = false; // 設(shè)置一個默認boolean標(biāo)記
// 判斷類上是否有Uid注解
if (uc.isAnnotationPresent(Uid.class)){
// 有Uid注解 要求必須存在int類型的uid屬性
// 獲取類的屬性
Field[] fields = uc.getDeclaredFields();
for (Field field : fields){
// 表示這個類的是合法的類悲柱,有@Uid注解,類中存在int類型的uid
if ("uid".equals(field.getName()) && "int".equals(field.getType().getSimpleName())){
isOk = true;// 表示合法
break;
}
}
// 判斷是否合法
if (!isOk){//不合法
throw new HasNotUidPropertyException("被@Uid注解的類必須要有一個int類型的uid屬性");
}
}
}
}
/*
自定義異常
*/
class HasNotUidPropertyException extends RuntimeException{
public HasNotUidPropertyException() {
}
public HasNotUidPropertyException(String message) {
super(message);
}
}
/*
自定對象
*/
@Uid
class User{
// int uid;
String name;
String password;
}
/**
* Target:只允許該注解可以標(biāo)注類
* Retention:這個注解可以被反射
*
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Uid{
}