ジェネリック
一般的な導出
例:下方変換のデモンストレーション
package Project.Study.Genericity;
class Point{ //定义坐标类
private Object x; //可以保存任意数据
private Object y; //可以保存任意数据
public Object getX() {
return x;
}
public Object getY() {
return y;
}
public void setX(Object x) {
this.x = x;
}
public void setY(Object y) {
this.y = y;
}
}
public class Test {
public static void main(String args[]){
Point p=new Point(); //实例化Point类数据
p.setX("东经100度"); //设置坐标数据
p.setY(10); //设置坐标数据
System.out.println("x坐标:"+p.getX()+"y坐标"+p.getY());
//根据设置好的坐标取出数据进行操作
String x=(String)p.getX(); //取出坐标数据
String y=(String)p.getY(); //取出坐标数据
System.out.println("x坐标:"+x+"y坐标"+y);
}
}
//结果
//Exception in thread "main" java.lang.ClassCastException: class //java.lang.Integer cannot be cast to class java.lang.String //(java.lang.Integer and java.lang.String are in module java.base of //loader 'bootstrap')
// at Project.Study.Genericity.Test.main(Test.java:30)
//x坐标:东经100度y坐标10
例:ジェネリックを使用して変換操作を削減する
package Project.Study.Genericity;
//此时的T在Point类定义上只表示一个标记,在使用时需要为其设置具体的类型
class Point<T>{
private T x; //此属性的类型不知道,由Point类使用时的动态决定
private T y; //此属性的类型不知道,由Point类使用时的动态决定
public T getX() {
return x;
}
public T getY() {
return y;
}
public void setX(T x) {
this.x = x;
}
public void setY(T y) {
this.y = y;
}
}
public class Test {
public static void main(String args[]){
Point<String> p=new Point<String>(); //实例化Point类数据,设置泛型为String
p.setX("东经100度");
p.setY("北纬20度");
System.out.println("x坐标:"+p.getX()+"y坐标"+p.getY());
String x=p.getX(); //取出坐标数据,不再需要强制类型转换
String y=p.getY(); ////取出坐标数据,不再需要强制类型转换
System.out.println("x坐标:"+x+"y坐标"+y);
}
}
//结果
//x坐标:东经100度y坐标10
//x坐标:东经100度y坐标10
ヒント:クラスには複数の汎用タグを定義できます。
class Point<P,R>{
public R fun(P p){
return null;
}
}
ジェネリックを使用したい場合、ジェネリックが採用できる型はクラスのみ、つまり基本型ではなく、参照型のみであることに注意してください。
ワイルドカード
例:ワイルドカード「?」の使用
package Project.Study.Genericity;
class Message<T>{
private T msg;
public void setMsg(T msg){
this.msg=msg;
}
public T getMsg() {
return msg;
}
}
public class Test1 {
public static void main(String args[]){
Message<Integer>message1=new Message<>();
Message<String>message2=new Message<>();
message1.setMsg(30);
message2.setMsg("Hello World");
fun1(message1); //引用传递
fun2(message2);
}
public static void fun1(Message<?> temp){ //不能设置,但是可以取出
System.out.println(temp.getMsg());
}
public static void fun2(Message temp){ //默认使用Object作为泛型类型,可以在方法中随意修改对象内容(即使类型不符合),这种做法是不严谨的
temp.setMsg(100);
System.out.println(temp.getMsg());
}
}
//结果
//30
//100
上記のfun2()では、ワイルドカード「?」を使用して、データを任意に変更するこの操作を制限する必要があります。したがって、「?」で設定されたジェネリック型は、取り出せるが設定できないという意味であり、一度設定すると、プログラムのコンパイル時にエラーメッセージが表示されます。
"?Extends class":ジェネリックの上限を設定します。これは、宣言とメソッドパラメータで使用できます。
?Numberの拡張:NumberまたはNumberのサブクラス(Integer、Double、...)を設定できることを意味します
例:ジェネリックの上限を設定する
package Project.Study.Genericity;
class Message<T extends Number>{ //设置泛型上限,只能是Number或Number子类
private T msg;
public void setMsg(T msg){
this.msg=msg;
}
public T getMsg() {
return msg;
}
}
public class Test1 {
public static void main(String args[]){
Message<Integer>message1=new Message<>(); //Integer是Number子类
message1.setMsg(30);
fun1(message1); //引用传递
}
public static void fun1(Message<? extends Number> temp){ //定义泛型上限
System.out.println(temp.getMsg());
}
}
//结果
//30
"?Super class":メソッドパラメータで使用されるジェネリックの下限を設定します。
?スーパー文字列:設定できるのは文字列またはその親オブジェクトのみです。
例:ジェネリックの下限を設定する
package Project.Study.Genericity;
class Message<T>{ //定义泛型
private T msg;
public void setMsg(T msg){
this.msg=msg;
}
public T getMsg() {
return msg;
}
}
public class Test1 {
public static void main(String args[]){
Message<String>message1=new Message<>();
message1.setMsg("Hello World"); //设置属性内容
fun1(message1); //引用传递
}
public static void fun1(Message<? super String> temp){ //定义泛型下限
System.out.println(temp.getMsg());
}
}
//结果
//Hello World
汎用インターフェース
いずれの場合でも、インターフェースを使用する場合は、対応するサブクラスを定義する必要があります。汎用インターフェースサブクラスの場合、次の2つの実装があります。
実装1:サブクラスで汎用タグを設定し続ける
例:
package Project.Study.Genericity;
interface IMessage<T>{ //定义泛型接口
public void print(T t);
}
class MessageImpl<S>implements IMessage<S>{ //在子类继续设置泛型,此泛型也作为接口中的泛型类型
public void print(S t){
System.out.println(t);
}
}
public class Test2 {
public static void main(String[] args){
IMessage<String>msg=new MessageImpl<String>();
msg.print("HelloWorld");
}
}
//结果
//HelloWorld
実装方法2:サブクラスにジェネリック型は設定されていませんが、ジェネリック型は親クラスのインターフェースに明示的に定義されています。
package Project.Study.Genericity;
interface IMessage1<T>{
public void print(T t);
}
class MessageImpl1 implements IMessage1<String>{
public void print(String t){
System.out.println(t);
}
}
public class Test3 {
public static void main(String [] args){
IMessage1<String>msg=new MessageImpl1();
msg.print("HelloWorld");
}
}
//结果
//HelloWorld
一般的な方法
package Project.Study.Genericity;
public class Test4 {
public static void main(String [] args){
String str=fun("HelloWorld");
System.out.println(str.length());
}
/**
* 此方法为泛型方法,T的类型由传入的参数类型决定
* 必须在方法返回值前明确定义泛型标记
* @param t 参数类型,同时也决定了返回值类型
* @param <T>
* @return 直接返回设置进来的内容
*/
public static <T>T fun(T t){
return t;
}
}
//结果
//10