简体   繁体   English

在Java和数字类型中使用泛型

[英]Using generics in Java and numeric types

Hey there I have just started Java for a course I will be taking soon (yeah I'm a nerd, I study before I have start the class). 嘿,我刚刚开始学习Java课程,我很快开始学习(是的,我是一个书呆子,我在开始上课前学习)。 I wanted to cram a few concepts together to learn how everything works together in Java. 我想把几个概念放在一起,以了解一切如何在Java中协同工作。

Now, what I wanted to try to do is a simple Shape (Forme in french) class which has a least 1-2 classes inheriting from it and make a few instances inside a collections object. 现在,我想要尝试做的是一个简单的Shape(Forme in french)类,它至少有1-2个类继承自它,并在集合对象中创建一些实例。 I also wanted to make those classes generics to try that out as well. 我也想让那些类泛型也尝试一下。 That is the part I'm having trouble with. 那是我遇到麻烦的部分。

I'm very used to C++ so that may be where the confusion lies, but it seems that I can't use generics so that, for example, I can specify that dimensions will be in, say, Integer or Double or Float or whatever. 我已经习惯了C ++,所以这可能是混乱的地方,但似乎我不能使用泛型,所以,例如,我可以指定尺寸将在,例如,Integer或Double或Float或者其他。 Is it possible ? 可能吗 ?

The GetArea() method below can't compile because of base and hauteur . 由于basehauteur下面的GetArea()方法无法编译。

package testconcepts;

import java.util.*;
import java.lang.*;

abstract class Forme <T extends Number> {
    protected String nom_forme;

    String NomForme() { return nom_forme; }

    abstract Double GetArea();
}

class Triangle <T extends Number> extends Forme {
    protected T base, hauteur;

    Triangle() { 
        this.nom_forme = "TRIANGLE"; 
    }

    @Override
    Double GetArea() { return base * hauteur / 2; }

    T GetBase() { return base; }
    T GetHauteur() { return hauteur; }
    void SetBase(T base) { this.base = base; }
    void SetHauteur(T hauteur) { this.hauteur = hauteur; }
}

public class TestConceptsJava {
    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        list.add(new Triangle<Double>());
    }
}

Notice that I also cannot make assignments to 0 in the constructor because of type issues. 请注意,由于类型问题,我也无法在构造函数中将赋值赋值为0。

Also, I know there are very similar topics, but I haven't found a solution to my problem yet in those other questions. 此外,我知道有非常相似的主题,但我还没有找到解决我的问题的其他问题。

TLDR How can I make work generics with primitive type wrappers (Double, Integer..) ? TLDR如何使用基本类型包装器(Double,Integer ..)创建工作泛型?

So your problem is this line I guess: 所以你的问题就在这一行我猜:

Double GetArea() { return base * hauteur / 2; }

The reason you receive an error is because the * operator is undefined for objects of type Number . 收到错误的原因是因为对于Number类型的对象,未定义*运算符。 Since you know that you will be dealing with int s and double s (I assume), you can try this: 既然你知道你将处理int s和double s(我假设),你可以试试这个:

Double GetArea() { return base.doubleValue() * hauteur.doubleValue() / 2; }

As a note, usually we start method names with a lower case letter, ie getArea() . 作为注释,通常我们使用小写字母开始方法名称,即getArea()

In GetArea(), you're calling the * operator on two classes. 在GetArea()中,您在两个类上调用*运算符。 How much sense would it make to say something like: 说出以下内容会有多大意义:

Object o1 = //whatever;
Object o2 = //whatever;

return o1 * o2;

Not much right? 不太对吗? You can't multiply two classes. 你不能将两个类相乘。 What you actually want to do is multiply the underlying value of those wrapper classes (which is not done implicitly for you in Java). 您实际想要做的是将这些包装类的基础值相乘(这在Java中不是为您隐式完成的)。 Rewriting GetArea() like this should solve your problem: 像这样重写GetArea()可以解决你的问题:

Double GetArea() { return base.doubleValue() * hauteur.doubleValue() / 2; }

Note that you'll also have to use the underlying value everywhere else that you care about it in that class. 请注意,您还必须在该类中关注它的任何其他地方使用基础值。

Changing to Double GetArea() { return base.doubleValue() * hauteur.doubleValue() / 2; } 更改为Double GetArea() { return base.doubleValue() * hauteur.doubleValue() / 2; } Double GetArea() { return base.doubleValue() * hauteur.doubleValue() / 2; } will make code compile, but this is bad idea in Java, since generics in java aren't for this. Double GetArea() { return base.doubleValue() * hauteur.doubleValue() / 2; }将代码编译,但这是在Java中糟糕的主意,因为在Java泛型是不是这个。 They just, basically, to ensure static type safety when using collections of objects. 基本上,它们在使用对象集合时确保静态类型安全。

Java has no operator overloading, so you can't expect * to work for anything except primitive types. Java没有运算符重载,所以你不能指望*除了原始类型之外的任何东西都可以工作。

I'd suggest reading basic Java generics tutorial to get an idea what are they for in Java: http://docs.oracle.com/javase/1.5.0/docs/guide/language/generics.html 我建议阅读基本的Java泛型教程,以了解它们在Java中的用途: http//docs.oracle.com/javase/1.5.0/docs/guide/language/generics.html

Look at this part of your calculation: 看看你计算的这一部分:

base * hauteur

Since both base and hauteur are declared using a wrapper class, you cannot use the * operator like you can with primitive types. 由于这两个 basehauteur所使用的包装类中声明,你不能使用*像您可以与原始类型操作。 Instead, you need to get the value explicitly: 相反,您需要明确获取值:

base.doubleValue() * hauteur.doubleValue()

Note that this wouldn't be a problem if either base or hauteur were declared with a primitive type. 请注意,如果使用基本类型声明basehauteur ,则这不会成为问题。 Then the Java compiler would be able to use auto-unboxing to convert the other one to the appropriate type and do any implicit conversions needed. 然后Java编译器将能够使用自动拆箱将另一个转换为适当的类型并执行所需的任何隐式转换。

What you're looking for is called "auto-(un)boxing". 您正在寻找的是“自动(非)拳击”。 Unfortunately, operations on T must be valid for all subtypes of Number , and "auto-(un)boxing" is not such an operation (eg, it will not work with BigInteger ). 不幸的是,对T操作必须对Number 所有子类型有效,并且“auto-(un)boxing”不是这样的操作(例如,它不适用于BigInteger )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM