2009-05-08 4 views
1

Можно ли проверить, был ли символ передан в метод, который требует int? Например, если у вас есть функция foo (int bar), и кто-то использует эту функцию, например foo ('t'), вы можете узнать, что введен символ, а не int? Я знаю, что char преобразуется в int, но я пытаюсь ограничить что-либо, кроме чистых целых чисел, проходящих через функцию.Как проверить, передан ли символ как int

Cheers

ответ

8

Вы можете использовать Integer вместо int.

void foo(Integer bar) { } 

Если вы попытаетесь вызвать foo ('A'), вы получите ошибку компилятора.

+0

А я думаю, что это то, что я должен реализовать благодаря: D. И спасибо за подлый решение Pax, очень элегантный способ обойти его :) – user100617

+0

Использование Integer вместо int может нести значительные накладные расходы более чем на 10x –

+0

Вы можете сделать это временно, проверить, что код все еще компилируется и возвращается изменение если есть. –

9

Нет, это невозможно, потому что сама Java обновляет char до int, если это возможно.

Вы могли бы сделать перегрузку вашей функции, которая принимает параметр char вместо с int который может бросить исключение, но это не остановит никого из литья char к int и называя версию int.

Абсолютно никакой разницы между символьной константой 'A' не отличает целое число и целое число 65, поэтому было бы невозможно отличить случаи.

Обновление от Pax:

Я считаю, что явное приведение НЕ прохождения char, это вызывающий превращение char к int затем передавая int. Это решение улавливает непреднамеренное прохождение char.

Pinching чей-то код от другого ответа, который был бы:

public class Test { 
    private static void someMethod(char c) throws Exception { 
     throw new Exception("I don't think so, matey!"); 
    } 
    private static void someMethod(int i) { 
     System.out.println(i); 
    } 
    public static void main(String[] args) throws Exception { 
     someMethod(100); 
     someMethod('d'); 
    } 
} 

Это приводит к:

100 
Exception in thread "main" java.lang.Exception: I don't think so, matey! 
    at Test.someMethod(Test.java:4) 
    at Test.main(Test.java:13) 
+0

Благодарим за ответы ребята. Я не думал, что есть способ отличить их. Cheers – user100617

+0

Но вы можете утверждать, что явное кастинг НЕ передает символ, это вызывающий, преобразующий символ в int, а затем передающий int. Перегруженная функция должна поймать другую (подлый подход, кстати, так что я выставляю вас). – paxdiablo

0

Если ваши числа не ограничены диапазоном, который находится вне зоны действия полукокса, то вы не можете сделать это, так как вы не можете определить, является ли значение 64 значением int или char.

3

Отливка char к int будет происходить во время компиляции, так что это будет невозможно определить, является ли char был принят в, или int был принят в.

Для того, чтобы проиллюстрировать, давайте рассмотрим исходный код и полученный байт-код программы, которая имеет someMethod(int), которая называется пропусканием char и int:

Исходный код:

class CharIntCast 
{ 
    private static void someMethod(int i) 
    { 
    } 

    public static void main(String[] args) 
    { 
     someMethod(100); 
     someMethod('d'); 
    } 
} 

ByteCode :

Compiled from "CharIntCast.java" 
class CharIntCast extends java.lang.Object{ 
CharIntCast(); 
    Code: 
    0: aload_0 
    1: invokespecial #1; //Method java/lang/Object."<init>":()V 
    4: return 

private static void someMethod(int); 
    Code: 
    0: return 

public static void main(java.lang.String[]); 
    Code: 
    0: bipush 100 
    2: invokestatic #2; //Method someMethod:(I)V 
    5: bipush 100 
    7: invokestatic #2; //Method someMethod:(I)V 
    10: return 

} 

Как можно видеть в байт-код, оба значения 100 и 'd' уже обрабатываются как целое число, когда оно направляется в стек командой bipush перед выполнением вызова к someMethod.

Следовательно, во время выполнения не удастся выяснить, был ли аргумент метода либо int, либо char, так как кастинг выполняется компилятором.

4

Я пытаюсь ограничить что-нибудь другое , чем чистые целые получать с помощью функции .

У вас немного концептуальное несоответствие с Java. A char в Java - это всего лишь число; тот факт, что вы используете тип char вместо типа int, - это то, что вы хотите число, равное 16 битам вместо 32 бит.

A char - это всего лишь число, которое идет от 0 до 65535. int - это всего лишь номер, который идет от -2,147,483,648 до 2,147,483,647.

Теперь я понимаю, что вы хотите, чтобы люди не вызывали ваш метод с бессмысленными вещами, такими как foo('t'). Однако, как только ваша программа скомпилирована, Java фактически преобразует этот вызов в foo(116).

Фактически, кто-то, вызывающий ваш метод с символом в качестве параметра, такой же глупый, как вызов вашего метода с произвольным числом. Если вы застряли в такой ситуации, рассмотрите эти возможности:

  • Неправильно ли некоторые символы вводят ваш метод?

    Например, вы хотите значение яркости от 0 до 255, а setBrightness('Δ') - это фактически setBrightness(916).

    Бросьте исключение - вы должны делать это в любом случае!

  • Вы хотите, чтобы символ, представляющий числовое значение, анализировался?

    Например, вы хотите иметь значение яркости от 0 до 9, а setBrightness('5') должно быть действительно setBrightness(5).

    Разбор символов в виде строки.

_

char a = '5'; 
String a_s = String.valueOf(a); 
int a_i = Integer.parseInt(a_s); 
setBrightness(a_i) 
  • метод делать ли все правильно, но передавая символ в качестве параметра глупо?

    Например, вы хотите, чтобы значение яркости находилось в диапазоне от 0 до 1000000, а setBrightness('q') просто потирает вас неправильно.

    Оставьте это в покое. Вызов setBrightness('q') - плохая форма, но это проблема другого кодера. Не делай этого сам, хотя! Вы будете пинать себя позже, когда вы копаете в таблице Unicode, пытаясь понять, что вы имели в виду в то время.

Смежные вопросы