Par exemple, je souhaite créer une fonction pouvant renvoyer n'importe quel nombre (négatif, zéro ou positif).
Cependant, en fonction de certaines exceptions, j'aimerais que la fonction renvoie Boolean
FALSE
Existe-t-il un moyen d'écrire une fonction pouvant renvoyer un int
ou un Boolean
?
Ok, donc cela a reçu beaucoup de réponses. Je comprends que j’aborde simplement le problème de manière incorrecte et que je devrais throw
une sorte d’exception dans la méthode. Pour obtenir une meilleure réponse, je vais vous donner un exemple de code. S'il vous plaît ne vous moquez pas :)
public class Quad {
public static void main (String[] args) {
double a, b, c;
a=1; b=-7; c=12;
System.out.println("x = " + quadratic(a, b, c, 1)); // x = 4.0
System.out.println("x = " + quadratic(a, b, c, -1)); // x = 3.0
// "invalid" coefficients. Let's throw an exception here. How do we handle the exception?
a=4; b=4; c=16;
System.out.println("x = " + quadratic(a, b, c, 1)); // x = NaN
System.out.println("x = " + quadratic(a, b, c, -1)); // x = NaN
}
public static double quadratic(double a, double b, double c, int polarity) {
double x = b*b - 4*a*c;
// When x < 0, Math.sqrt(x) retruns NaN
if (x < 0) {
/*
throw exception!
I understand this code can be adjusted to accommodate
imaginary numbers, but for the sake of this example,
let's just have this function throw an exception and
say the coefficients are invalid
*/
}
return (-b + Math.sqrt(x) * polarity) / (2*a);
}
}
Non, vous ne pouvez pas faire ça en Java.
Vous pouvez cependant renvoyer une Object
. Et en renvoyant un objet, vous pouvez techniquement renvoyer une classe dérivée telle que Java.lang.Integer
ou Java.lang.Boolean
. Cependant, je ne pense pas que ce soit la meilleure idée.
Vous pouvez techniquement faire ceci:
public <T> T doWork()
{
if(codition)
{
return (T) new Integer(1);
}
else
{
return (T) Boolean.FALSE;
}
}
Alors ce code compilerait:
int x = doWork(); // the condition evaluates to true
boolean test = doWork();
Mais vous pouvez très certainement rencontrer des exceptions d'exécution si la méthode retourne un type incorrect. Vous devez également renvoyer des objets au lieu de primitives, car T est effacé dans Java.lang.Object, ce qui signifie que le type renvoyé doit étendre Object (c’est-à-dire un objet). L'exemple ci-dessus utilise l'autoboxing pour obtenir un type de retour primitif.
Je ne recommanderais certainement pas cette approche car, IMO, vous devez évaluer votre utilisation de la gestion des exceptions. Vous capturez des exceptions dans des cas exceptionnels si vous pouvez faire quelque chose avec cette exception (c'est-à-dire restaurer, persister, réessayer, etc.). Les exceptions sont une exception au flux de travail attendu, et n'en font pas partie.
non. le mieux que vous puissiez faire est de retourner sur l'instance d'une classe qui gère tout ce que vous pourriez vouloir retourner.
quelque chose comme
public class ReturnObj {
public bool yesno; // yes or no
public int val; // for int values
public String mode; // mode describing what you returned, which the caller will need to understand.
}
évidemment, vous devez jouer avec les noms ...
En outre, cela ressemble à une odeur de code. Vous pourrez peut-être supprimer le besoin de faire quelque chose comme ceci en qualifiant quel chemin vous voulez en dehors de votre fonction, puis appeler une fonction spécifique pour obtenir un booléen ou une fonction spécifique pour obtenir un int, selon la qualification.
Ecrivez une fonction qui retourne une Object
. Demandez-lui de renvoyer les objets wrapper Boolean
ou Integer
. Ensuite, utilisez instanceof pour déterminer lequel utiliser.
La plupart des langues gèrent votre exemple spécifique sans Exceptions ni types d'union, car le point flottant IEEE inclut une représentation pour NaN. En Java, utilisez Double.NaN:
public static double quadratic(double a, double b, double c, int polarity) {
double x = b*b - 4*a*c;
// When x < 0, Math.sqrt(x) retruns NaN
if (x < 0) {
return Double.NaN;
}
return (-b + Math.sqrt(x) * polarity) / (2*a);
}
Cela produit votre sortie exacte que vous vouliez:
x = 4.0
x = 3.0
x = NaN
x = NaN
Les exceptions sont The Old Java Way pour résoudre des problèmes similaires:
public static double quadratic(double a, double b, double c, int polarity) {
double x = b*b - 4*a*c;
// When x < 0, Math.sqrt(x) returns NaN
if (x < 0) {
throw new Exception("NaN")
}
return (-b + Math.sqrt(x) * polarity) / (2*a);
}
Voici votre code client pour une exception.
a=1; b=-7; c=12;
// x = 4.0
try {
System.out.println("x = " + quadratic(a, b, c, 1));
} catch (Exception iae) {
System.out.println("Oopsie: " + iae.getMessage());
}
// x = 3.0
try {
System.out.println("x = " + quadratic(a, b, c, -1));
} catch (Exception iae) {
System.out.println("Oopsie: " + iae.getMessage());
}
// "invalid" coefficients.
a=4; b=4; c=16;
// Oopsie: NaN
try {
System.out.println("x = " + quadratic(a, b, c, 1));
} catch (Exception iae) {
System.out.println("Oopsie: " + iae.getMessage());
}
// Oopsie: NaN
try {
System.out.println("x = " + quadratic(a, b, c, -1));
} catch (Exception iae) {
System.out.println("Oopsie: " + iae.getMessage());
}
Pour véritablement transmettre ou renvoyer des types non liés à une méthode, vous souhaitez que les types Union ne soient pas pris en charge par Java. Mais Paguro fournit Union Types que vous pouvez utiliser en Java comme ceci (en utilisant Ou):
public static Or<Double,String> quadratic(double a, double b,
double c, int polarity) {
double x = b*b - 4*a*c;
// When x < 0, Math.sqrt(x) retruns NaN
if (x < 0) {
return Or.bad("NaN");
}
return Or.good((-b + Math.sqrt(x) * polarity) / (2*a));
}
@Test public void testQuadradic() {
double a, b, c;
a=1; b=-7; c=12;
// x = Good(4.0)
System.out.println("x = " + quadratic(a, b, c, 1));
// x = 3.0
System.out.println(
(String) quadratic(a, b, c, -1)
.match(good -> "x = " + good,
bad -> "Oopsie: " + bad));
// "invalid" coefficients.
a=4; b=4; c=16;
// x = Bad("NaN")
System.out.println("x = " + quadratic(a, b, c, 1));
// Oopsie: NaN
System.out.println(
(String) quadratic(a, b, c, -1)
.match(good -> "x = " + good,
bad -> "Oopsie: " + bad));
}
Pour votre exemple spécifique, utilisez simplement Floating Point. Pour une solution plus générale, je trouve les types d'union plus utiles que les exceptions. Vous pouvez utiliser des types d'union comme arguments d'une méthode pouvant prendre deux entrées différentes sans interface ni ancêtre commune. Ils sont également plus favorables à la programmation fonctionnelle.
Non, une référence à un client.
Vous pouvez écrire un objet de réponse qui encapsule un booléen et un int et définir les valeurs en fonction de vos caprices.
Mais si j'étais un utilisateur, je penserais que votre conception est source de confusion.
mon professeur a eu une idée géniale d'une méthode semblable à tryParse C # en Java
import Java.util.Scanner;
public class Program {
static Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
System.out.println("Enter number");
String input = scanner.next();
int[] num ={0};
if(tryParse(input,num))
System.out.println(num[0] * num[0]);
}
static boolean tryParse(String inputString,int[] outputInt){
try{
outputInt[0] = Integer.parseInt(inputString);
return true;
}catch(Exception e){
return false;
}
}
}
Cela peut ne pas être la meilleure solution en fonction de ce que vous voulez faire, mais un moyen simple de résoudre le problème consiste à demander à la fonction de renvoyer un entier ou une constante en dehors de la plage possible (telle que RETURNED_FALSE/TRUE) et de vérifier cela .